Article Title
Content goes here.
Tech tutorials, coding best practices, and deep dives into modern web development — all written for developers who love to learn.
A deep dive into useState, useEffect, and custom hooks with real-world patterns.
Read Full Post →Clear examples and layout strategies to help you choose the right tool.
Read Full Post →One of JS’s trickiest concepts, broken down with practical examples.
Read Full Post →Hi, I'm Aries, a full-stack developer, open-source contributor, and tech educator passionate about clean code, modern frameworks, and sharing knowledge.
AriesBlaze is where I write about what I learn — from deep dives into React and JavaScript, to CSS architecture, DevOps, and personal productivity for developers.
My goal? To help you write better code, build faster, and enjoy the craft of development.
A deep, practical dive into one of JavaScript’s most powerful — and misunderstood — features.
If you’ve been writing JavaScript for more than a few weeks, you’ve likely heard the term closure. It sounds mysterious, but at its core, a closure is simply a function that remembers the variables from the environment in which it was created — even after that environment no longer exists.
To truly understand closures, we must first understand scope — how JavaScript determines where variables are accessible.
Scope defines the accessibility of variables, functions, and objects during runtime. JavaScript uses lexical (static) scope, meaning scope is determined by where variables are declared in the source code.
let or const inside {} blocks.
function greet() {
var userName = "Alice";
console.log(userName); // ✅ Works
}
greet();
console.log(userName); // ❌ ReferenceError
function outer() {
let outerVar = "I'm outside!";
function inner() {
console.log(outerVar); // ✅ Accessible!
}
inner();
}
outer(); // → "I'm outside!"
A closure is a function that retains access to variables from its outer scope — even after the outer function has finished executing.
function createCounter() {
let count = 0;
return function() {
count++;
console.log("Count:", count);
};
}
const counter = createCounter();
counter(); // → 1
counter(); // → 2
function createUser(name) {
let balance = 0;
return {
getName: () => name,
deposit: (amount) => { balance += amount; },
getBalance: () => balance
};
}
const user = createUser("Aries");
user.deposit(100);
console.log(user.getBalance()); // → 100
for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i); // → 0, 1, 2
}, 100);
}
Closures are not magic — they’re a natural consequence of JavaScript’s scoping rules. Master them, and you’ll write more robust, maintainable, and powerful code.
A complete guide to useState, useEffect, useContext, useReducer, and building your own custom hooks.
React Hooks revolutionized how we write components — moving from class-based logic to clean, reusable functions. In 2025, hooks are no longer optional; they're the foundation of modern React development.
In this guide, we’ll go beyond the basics and explore real-world patterns, common pitfalls, and advanced techniques used by senior developers.
Hooks are functions that let you “hook into” React state and lifecycle features from function components. They don’t work inside classes — but they let you use React without classes.
Key rules:
useState is the most basic hook — it lets you add state to functional components.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
// In React, you would use JSX like below:
// return (
//
// Count: {count}
// <button onClick={() => setCount(count + 1)}>
// Increment
// </button>
//
// );
// For plain JS/HTML, you can use:
// document.getElementById('incrementBtn').addEventListener('click', function() {
// count++;
// document.getElementById('countDisplay').textContent = count;
// });
// Or just display the JSX as a code example:
return null;
}
✅ Use setCount to update state — don’t mutate directly.
✅ The setter function can also take a callback: setCount(prev => prev + 1) (safe for async updates).
useEffect lets you perform side effects (data fetching, subscriptions, DOM manipulation) in function components.
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => setUser(data));
}, [userId]); // ← Dependency array
return {user ? user.name : 'Loading...'};
}
🔑 The dependency array [userId] tells React when to re-run the effect.
⚠️ Missing it? You’ll get infinite loops or stale data.
For subscriptions or event listeners, return a cleanup function:
useEffect(() => {
function handleResize() {
console.log(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
useContext lets you access context values without passing props down manually.
import { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function App() {
return (
);
}
function Toolbar() {
return (
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return ;
}
When state logic becomes complex, useReducer is a better alternative to useState.
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
// In a React component, you would use:
// return (
// <>
// Count: {state.count}
// <button onClick={() => dispatch({ type: 'increment' })}>+</button>
// <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
// >
// );
return null;
}
Custom hooks are just functions that use other hooks. Name them with useXxx.
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setStoredValue = (newValue) => {
setValue(newValue);
localStorage.setItem(key, JSON.stringify(newValue));
};
return [value, setStoredValue];
}
Now use it anywhere:
function DarkModeToggle() {
const [darkMode, setDarkMode] = useLocalStorage('darkMode', false);
return (
// JSX example, not executable in HTML:
// <button onClick={() => setDarkMode(!darkMode)>
// {darkMode ? 'Light' : 'Dark'} Mode
// </button>
);
}
Use the ESLint plugin eslint-plugin-react-hooks to catch violations early.
useState: For simple state.useEffect: For side effects and lifecycle.useContext: For global state.useReducer: For complex state logic.useCustom: For reusable logic.Master React Hooks, and you’ll write cleaner, more maintainable, and more powerful components. They’re not magic — just smart abstractions that make React fun again.
Discover semantic tags, accessibility, and modern features that make HTML more powerful than ever.
HTML is often seen as the "simple" part of web development — just tags and content. But modern HTML is far more powerful than many realize. It’s not just about structure; it’s about meaning, accessibility, and SEO.
Let’s go beyond
Semantic elements clearly describe their purpose to both the browser and developer.
Content goes here.
✅ Benefits:
ARIA (Accessible Rich Internet Applications) adds extra context for assistive technologies.
Use
Use semantic input types for better UX and validation.
These provide built-in validation, mobile keyboard optimization, and visual controls.
Store extra info in HTML using
Access in JavaScript:
HTML isn’t just markup — it’s the foundation of accessible, SEO-friendly, and maintainable web apps. Use it wisely.
Powerful, underused CSS features that can simplify your code and boost performance.
CSS has evolved far beyond colors and margins. In 2025, modern CSS includes powerful layout tools, custom properties, and even logic — all without JavaScript.
Let’s explore some lesser-known but incredibly useful CSS features.
Finally, CSS can select parents based on children!
Supported in modern browsers (Chrome, Safari, Firefox).
Style components based on their container size — not the whole viewport.
Perfect for reusable components that adapt to their space.
Define reusable values and even update them with JavaScript.
Write CSS that works across languages (LTR and RTL).
These adapt to
No more margin hacks — use
CSS is more powerful than ever. Use these features to write cleaner, more maintainable, and more accessible styles.
Get the latest coding tips and tutorials straight to your inbox.
No spam. Unsubscribe anytime.
Want even more? Follow me for updates, tips, and project launches.
and explore what modern HTML can do.
Semantic HTML: Meaningful Markup
Article Title
ARIA: Enhancing Accessibility
role, aria-label, and aria-live to make dynamic content accessible.
HTML5 Input Types
Custom Data Attributes
data-* attributes.
Aries
const user = document.querySelector('.user-card');
console.log(user.dataset.userId); // → "123"
Summary
CSS You Probably Didn’t Know Existed (2025)
The :has() Selector (Parent Selector)
.card:has(.featured) {
border: 3px solid gold;
transform: scale(1.05);
}
/* Style a label if the input is invalid */
label:has(input:invalid) {
color: red;
}
Container Queries
.card-container {
container-type: inline-size;
}
@container (min-width: 300px) {
.card {
display: flex;
gap: 1rem;
}
}
CSS Custom Properties (CSS Variables)
:root {
--primary: #2563eb;
--radius: 0.5rem;
--transition: all 0.3s ease;
}
.button {
background: var(--primary);
border-radius: var(--radius);
transition: var(--transition);
}
/* Change theme dynamically */
document.documentElement.style.setProperty('--primary', '#7c3aed');
Logical CSS Properties
.box {
padding-inline-start: 1rem; /* left or right depending on dir */
margin-block-end: 0.5rem; /* bottom */
border-inline-end: 1px solid; /* right or left */
}
dir="rtl" automatically.
gap in Flexbox
gap in flex layouts.
.flex-container {
display: flex;
flex-direction: column;
gap: 1rem; /* Space between children */
}
Summary
:has(): Select parents based on children.gap: Clean spacing in flex and grid.Stay Updated
All links in the footer.