AriesBlaze

Code. Build.
Repeat.

Tech tutorials, coding best practices, and deep dives into modern web development — all written for developers who love to learn.

Read First Post GitHub

Latest Posts

React Hooks
React

Mastering React Hooks in 2025

A deep dive into useState, useEffect, and custom hooks with real-world patterns.

Read Full Post →
CSS Grid
CSS

CSS Grid vs Flexbox: When to Use Which

Clear examples and layout strategies to help you choose the right tool.

Read Full Post →
JS Closures
JavaScript

Understanding Closures and Scope

One of JS’s trickiest concepts, broken down with practical examples.

Read Full Post →

About AriesBlaze

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.

← Back to Posts

Understanding Closures and Scope in JavaScript

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.

What is Scope?

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.

Function Scope Example

function greet() {
  var userName = "Alice";
  console.log(userName); // ✅ Works
}
greet();
console.log(userName); // ❌ ReferenceError

Lexical Scope (Static Scope)

function outer() {
  let outerVar = "I'm outside!";
  function inner() {
    console.log(outerVar); // ✅ Accessible!
  }
  inner();
}
outer(); // → "I'm outside!"

What is a Closure?

A closure is a function that retains access to variables from its outer scope — even after the outer function has finished executing.

Closure Example: Counter

function createCounter() {
  let count = 0;
  return function() {
    count++;
    console.log("Count:", count);
  };
}
const counter = createCounter();
counter(); // → 1
counter(); // → 2

Why Are Closures Useful?

Real-World Example: Private State

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

Common Pitfall: Closures in Loops

for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // → 0, 1, 2
  }, 100);
}

Summary

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.

← Back to Posts

Mastering React Hooks in 2025

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.

What Are React Hooks?

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: Managing Local State

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: Side Effects Made Simple

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.

Cleanup with useEffect

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: Global State Without Prop Drilling

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 ; }

useReducer: Complex State Logic

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: Reuse Logic Across Components

Custom hooks are just functions that use other hooks. Name them with useXxx.

Example: useLocalStorage

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>
  );
}

Rules of Hooks

  1. Only Call Hooks at the Top Level: Don’t call hooks inside loops, conditions, or nested functions.
  2. Only Call Hooks from React Functions: Don’t call hooks from regular JavaScript functions.

Use the ESLint plugin eslint-plugin-react-hooks to catch violations early.

Summary

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.

← Back to Posts

Modern HTML: Beyond the Basics (2025)

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

and

and explore what modern HTML can do.

Semantic HTML: Meaningful Markup

Semantic elements clearly describe their purpose to both the browser and developer.

Article Title

Content goes here.

Copyright 2025

✅ Benefits:

  • Better accessibility (screen readers)
  • Improved SEO (search engines understand structure)
  • Cleaner, more maintainable code

ARIA: Enhancing Accessibility

ARIA (Accessible Rich Internet Applications) adds extra context for assistive technologies.





Use role, aria-label, and aria-live to make dynamic content accessible.

HTML5 Input Types

Use semantic input types for better UX and validation.







These provide built-in validation, mobile keyboard optimization, and visual controls.

Custom Data Attributes

Store extra info in HTML using data-* attributes.

Aries

Access in JavaScript:

const user = document.querySelector('.user-card');
console.log(user.dataset.userId); // → "123"

Summary

  • Use semantic HTML for better structure.
  • Add ARIA for accessibility.
  • Use input types for UX and validation.
  • Leverage data attributes for custom metadata.

HTML isn’t just markup — it’s the foundation of accessible, SEO-friendly, and maintainable web apps. Use it wisely.

← Back to Posts

CSS You Probably Didn’t Know Existed (2025)

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.

The :has() Selector (Parent Selector)

Finally, CSS can select parents based on children!

.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;
}

Supported in modern browsers (Chrome, Safari, Firefox).

Container Queries

Style components based on their container size — not the whole viewport.

.card-container {
  container-type: inline-size;
}

@container (min-width: 300px) {
  .card {
    display: flex;
    gap: 1rem;
  }
}

Perfect for reusable components that adapt to their space.

CSS Custom Properties (CSS Variables)

Define reusable values and even update them with JavaScript.

: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

Write CSS that works across languages (LTR and RTL).

.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 */
}

These adapt to dir="rtl" automatically.

gap in Flexbox

No more margin hacks — use gap in flex layouts.

.flex-container {
  display: flex;
  flex-direction: column;
  gap: 1rem; /* Space between children */
}

Summary

CSS is more powerful than ever. Use these features to write cleaner, more maintainable, and more accessible styles.

Stay Updated

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.
All links in the footer.