Yesterday we made something still. Today we'll teach it to move. Open the file again, kardeşim, we're adding ten lines of JavaScript and building a small daily-cups tracker: it opens with bismillâh before the first sip, marks the halfway point with a gentle shift of colour, and closes with alhamdulillah at the eighth glass. A simple habit that happens to fit the sunnah of naming Allah at the start of what we consume and thanking Him at the end. Same tools, same folder, no installers. The browser is our IDE.
If HTML is the nouns of a web page and CSS is the adjectives, JavaScript is the verbs. Press, open, close, save, show, hide, count, all verbs. Learn four commands, and you can build most small apps yourself, bismillâh.
The one tag you need
Add this anywhere inside your <body>, usually near the bottom:
<script>
console.log('The pen has been taught. Now the hand.')
</script>
Save, refresh, open the browser's DevTools with F12 (or Cmd+Option+I on macOS), and click the Console tab. You'll see the message. You just ran code, no compiler, no server; the browser read your words and ran them. Alhamdulillah.
Example 1: a cup counter, the essential eight lines
<button id="cup" type="button">Bismillâh</button>
<div id="count">0</div>
<script>
let n = 0
const cup = document.querySelector('#cup')
const countEl = document.querySelector('#count')
cup.addEventListener('click', () => {
n += 1
countEl.textContent = n
})
</script>
Eight lines. A complete, working interactive app. Let's read them together:
let n = 0, a memory cell that starts at zero.document.querySelector('#cup'), find the button whoseidiscup. Same selector grammar as CSS.addEventListener('click', …), "when the user clicks, run this function."n += 1, increment.countEl.textContent = n, replace the displayed number.
That's the whole vocabulary of interactive web pages: find an element, listen for an event, change something. You now know the recipe every framework is built on top of.
Example 2: mark the rhythm, colour progression and a gentle finish
The demo above has three small moments. At the third cup, the button and background shift to a deeper ocean blue, the day's started well. At five, a teal middle, halfway there. At eight, brand-purple and a quiet alhamdulillah with a short burst of light, the body has had what it needs, masallah.
Two small ideas carry most of the logic:
const TIERS = [
{ at: 3, phrase: 'Bismillâh, first sips done', col: '#1e7ab8' },
{ at: 5, phrase: 'Halfway, keep going', col: '#0f6fac' },
{ at: 8, phrase: 'Alhamdulillah, daily cups complete', col: '#5d00ff' }
]
cup.addEventListener('click', () => {
n += 1
countEl.textContent = n
const hit = TIERS.find(t => t.at === n)
if (hit) {
document.body.style.setProperty('--accent', hit.col)
ringEl.textContent = hit.phrase
}
})
Three techniques worth remembering:
-
Array.prototype.findreturns the first element that matches, clean way to look up the current milestone. -
body.style.setProperty('--accent', col)sets a CSS custom property from JavaScript. All the colours cascade from that one variable, the bead, the number, the heading, the ambient glow, and they animate smoothly because the CSStransitionhandles the fade. -
Do visuals in CSS, decisions in JS. Adding the
.celebrateclass to the cup at the eighth glass triggers a two-second keyframe animation defined in the stylesheet. JavaScript stays short and fast; CSS handles the choreography.
Example 3: remember across page reloads
The browser ships with a tiny key-value database called
localStorage. It is the easiest backend you will ever
meet, no server, no database file, no password. Persist your cup
count so it survives a tab close:
let n = Number(localStorage.getItem('cups-today') || 0)
countEl.textContent = n
cup.addEventListener('click', () => {
n += 1
countEl.textContent = n
localStorage.setItem('cups-today', n)
})
Click, close the tab, reopen, your count is still there. Ten lines of JavaScript just built an auto-saving habit tracker with no backend at all. Alhamdulillah for the simplicity.
Tricks worth carrying
-
querySelectorunderstands any CSS selector.document.querySelector('.card:nth-child(2) button')works. You already know the selector language from CSS. -
Prefer
textContentoverinnerHTML.innerHTMLrenders HTML, fine for trusted content, risky for user input.textContentalways treats the value as plain text. Safety first, cleverness second, there is a kind of adab in writing careful code. -
addEventListeneris the only event API you need. Forgetonclick="…"strings in HTML. One function, one place, cleaner code. -
localStorageholds about 5 MB per site. Counters, to-do lists, preferences, none of them need a backend. -
CSS custom properties +
transition= free animation. Change a variable from JS; let the browser smooth the rest.
What frameworks add, and what they don't replace
React, Vue, Svelte, these speed up two specific things:
rendering lists that change a lot and
reusing UI across many pages. If your project has
neither problem, you don't need a framework. A ten-line
<script> tag is perfectly serious engineering.
And the language itself, document.querySelector,
addEventListener, arrow functions,
localStorage, stays exactly the same underneath every
framework. Learn this once, carry it forever.
Takeaways
- JavaScript runs inside any HTML file with a
<script>tag, no setup needed. - Four things cover most interactivity: find, listen, change, remember.
- Put visuals in CSS, decisions in JS, the shape of a durable interactive app.
- The browser is your IDE. DevTools let you read, tweak, and debug live.
There is something quiet about a counter for a daily habit, intention made visible, kept by a tiny programme you wrote in ten lines. The sunnah asks us to name Allah at the start of what we consume (bismillâh) and to thank Him at the end (alhamdulillah); this small cup-counter does no more than frame that. A small tool, a small thing done well, inşallah.
Next post: "How a URL actually works, the 0.3 second journey", the six small protocols holding hands behind every page load.
Build small, build honest, and keep your code light.