<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Nonsoo | Developer. Writer. Tinkerer</title>
        <link>https://www.nonsoo.com/</link>
        <description>Welcome to my digital garden where I share what I'm learning about shipping great products, becoming a better developer and growing a career in tech.</description>
        <lastBuildDate>Thu, 06 Aug 2026 20:46:35 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Nonsoo | Developer. Writer. Tinkerer</title>
            <url>https://www.nonsoo.com/favicon/favicon-32x32.png</url>
            <link>https://www.nonsoo.com/</link>
        </image>
        <copyright>© 2026 Nonsoo</copyright>
        <category>React</category>
        <category>react</category>
        <category>programming</category>
        <category>css</category>
        <category>Programming</category>
        <category>conference</category>
        <category>Javascript</category>
        <category>python</category>
        <category>CSS</category>
        <item>
            <title><![CDATA[From Fiber to Async React]]></title>
            <link>https://www.nonsoo.com/posts/async-React</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/async-React</guid>
            <pubDate>Tue, 20 Jan 2026 01:04:36 GMT</pubDate>
            <description><![CDATA[The re-architecture of React's rendering algorithm represents a fundamental shift in how we should build React apps today. In this article, we trace that journey, showing how this algorithm's ability to abandon, interrupt, and prioritize renders underpins modern features like Activity, Suspense, and Transitions. We further introduce “Async React” as a new mental model and show how we can write and use async-first components, libraries, and suspense-enabled routers. Let’s write more declarative code, embrace async-first as the default and let React handle the rest.]]></description>
            <content:encoded><![CDATA[
It been some time since React 19 was released and since then we've seen new api's, hooks, and components that we can add to our apps. Some may argue that these are welcome changes while others may argue that these additions are cool but what's the point?

Let's pose the following question to begin! How would we go about doing data fetching or any async operation within React? Yes, of course we can reach for data-fetching/async libraries such as TanStack Query, swr, etc but let's pretend that we didn't have access to these libraries. How would we go about doing this?

The following code snippet may look familiar!

```jsx
const UsersList = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchUsers = async () => {
      setLoading(true);
      setError(null);

      try {
        const response = await fetch("/api/users");

        if (!response.ok) {
          throw new Error("Failed to fetch users");
        }

        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchUsers();
  }, []);
};
```

Traditionally, we would often reach for a `useEffect` to handle any asynchronous work (data fetching included) within our React applications. Here we've setup a component that calls the `fetchUsers` function when the component gets mounted to the DOM. We are then setting the data, loading, and error states appropriately such that we can display the correct UI to the user.

This approach works, but as many within the React community and the core React team have noted, this approach has many shortcomings and is not the advised method of handling asynchronous work with React.

Truthfully, React has always dealt with asynchronous work, even if it didn’t explicitly model it. Data fetching, code splitting, user input, animations, and navigation all happen asynchronously, yet for much of React’s history these concerns lived **around** the rendering system rather than **within** it.

As we've seen this meant that we were responsible for stitching together loading states, effects, and imperative updates so that we could keep the UI coherent while asynchronous work was completed. But should that be the responsibility of the application developer or should that responsibility be put elsewhere?

Let's consider the following; What would a React codebase look like if asynchronous work lived **within** the rendering system rather than **around** it? How would it change the way we approach building components, component systems and eventual whole applications?

The release of React 19 brought about the completion story of **"Async React"**, a term we'll unwrap throughout this article. We'll look at how "Async React" solves the coordination problem between UI and async work and we will attempt to answer the questions we posed above. We'll also look at new questions; Knowing that Async React is here, how do we expect React Library authors to build and compose the tools they expose to application developers?

It's a whole new world for developers in terms of how we structure our React applications and these changes can expand the types of experiences we can create. Throughout the article, we'll do a lot of deep dives, so these are just a few things to keep in mind while we explore the modern way of building React applications.

## The React Reconciler

You'll often notice that two important packages are installed when you create a React web app; **React** and **React-dom**. The React package is the library that allows us to describe UI as a function of some state. We often see this represented as the following equation **UI = f(state)** and we use JSX as the method to represent it.

Great! So where does `react-dom` come into play?

React-dom is the package that contains the **React reconciler** and **renderer for the web**. The reconciler is the engine responsible for comparing render outputs over time, scheduling work, and determining the minimal set of updates needed to be applied to the host platform<ToolTip>I use the term **Host platform** here because the React reconciler is platform agnostic. This means that it can be used with different platforms like the Web, mobile, different renderers, etc.</ToolTip>. The renderer then takes the output from the reconciler and applies it to the host platform; in this case the DOM.

The reconciler becomes important when speaking about Async React and how the new APIs were made possible. During [React conf 2017](https://www.youtube.com/watch?v=ZCuYPiUIONs) it was revealed that the React reconciler was rebuilt from the ground up as we went from what was known as the **stack reconciler** to **React Fiber**.

### Stack Reconciler

The stack reconciler was reconciliation engine that was used in the earlier versions of React up until React 16. It was designed to closely mirror how JavaScript executes function calls; therefore it relied directly on the call stack to traverse and render the component tree.

When a render was triggered—typically by a change in state—React would start at the root and recursively walk the component tree from top to bottom calling each components render function, reconciling the diff and then committing the result. This meant that once reconciliation/render began, React was required to complete the entire process before yielding control back to the browser.

We can see this in the following render example below. Press the **"start render"** button and see how rendering is taking place to update the count value within the dashboard component.

<AsyncReact_StackReconcilerDemo />

This approach was entirely synchronous and non-interruptible. All rendering work happened in a single pass, and all updates were treated with the same priority. While this made the system straightforward and predictable, it also meant that long renders could block the main thread, delaying user input and causing visible stutters in complex applications.

Considering the limitations of the stack reconciler, could we imagine a world where improvements could be made?

**POP Quiz!**
<AsyncReact_StackReconcilerTrueOrFalse />

### React Fiber

Enter **React Fiber**; a complete rewrite of React’s reconciler which was introduced in React 16 to address the limitations of the stack-based approach. Instead of implementing rendering in one single uninterrupted pass, Fiber would implement its own internal representation of the component tree--a Fiber Tree--and its own scheduling model.

In Fiber, each component is represented as a unit of work (a fiber) which can be processed independently. Rendering is broken into small, incremental steps, allowing React to pause work, yield to the browser <ToolTip>**Cooperative Scheduling** -- By yielding control back to the browser, React ensures that animations and interactions are not blocked, improving the overall user experience)</ToolTip>, and resume later. This means that Fiber splits the **reconciliation/rendering phase** and **commit phase** into two independent processes.

<Aside tag="FYI" title="The Fiber Node">
A Fiber node is a lightweight object that describes the metadata associated with a component. Importantly, each Fiber contains pointers that link it to its parent, child, and sibling components. A very contrived fiber node can be seen below however the full implementation can be viewed within the react codebase.

<AsyncReact_FiberNodeAside />

Since each Fiber represents a discrete unit of work, React can process the tree one unit at a time, rather than relying on a recursive function call that must run to completion. Between units, React can check whether it should continue rendering or yield control back to the browser. If rendering needs to pause, React simply stops traversal, retains its place in the Fiber tree, and yields. When work resumes, React continues from the next Fiber as if nothing happened.

This process is known as time slicing, and it is a direct consequence of modeling rendering work as a JavaScript object.

</Aside>

During the reconciliation/rendering (now referred to as the reconciliation phase), a list of all changes to be rendered in the UI is generated but does not get committed to the DOM. Rather, the changes are scheduled to be committed in the next phase. The **commit phase**, is when these changes are committed to the DOM.

The important thing to note here is that the **reconciliation phase** can be interrupted, paused/resumed, and discarded completely. The **commit phase** **cannot** be interrupted; therefore once the commit phase starts, it must finish before any other work can be done.

**POP Quiz!**
<AsyncReact_FiberTrueOrFalse />

Since the **reconciliation phase** can be interrupted, it suggests that the two independent pieces of work can be within the **reconciliation phase** and then progress into the **commit phase** out of order. This allows Fiber to introduce the concept of prioritization when speaking about showing render updates within the DOM.

Fiber allows React to schedule high-priority updates first while deferring lower-priority updates, thereby improving both perceived performance and user experience. We can imagine that typing into an input is more urgent than rendering data that just finished loading in the background. So why not defer rendering of the data so that we can show the state of the input field immediately. The rendering of the data will just happen after the user is done typing. This is what we mean by improved perceived performance.

So what are the priorities for Fiber? They are as follows:

- Synchronous Work (involves clicking/typing -- works like the stack reconciler)
- Task Work
- Animation (started by **`requestAnimationFrame()`** )
- high priority
- low priority
- off-screen (anything not currently in view but would be nice to have rendered in case it gets shown)

Understanding these priority groups will be important later on when we speak of the APIs, hooks, and components that were introduced in React 18 and 19. But the core thing here is that without the move to Fiber the concept of **Async React** would not be possible.

<Aside tag="FYI" title="More on the reconciler">
For an in-depth look at the reconciler and React fiber, checkout the [Lin Clark's Talk, A Cartoon Intro to Fiber](https://www.youtube.com/watch?v=ZCuYPiUIONs) or [Brandon's talk, Algebraic effects, Fibers, Coroutines Oh my](https://www.youtube.com/watch?v=7GcrT0SBSnI)!

You can also look into these browser APIs which are pertinent to the fiber reconciler: [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback), and [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame).

</Aside>

## Modern React Features

React Fiber was such a monumental feat of engineering as it introduced the ability to have interruptible renders, cooperative scheduling, prioritization, and so much more. With these concepts introduced, we could begin to imagine a new world of building React applications. However, the core entities that were missing from the Fiber release were the APIs that would allow developers to hook into this new way of building.

<Aside tag="FYI" title="APIs definition">
To note, I use the term APIs loosely here to refer to hooks, functions, and components that are available by React. However, React has a formal definition of **API** which refers to the functions made available by the React package.

Throughout the article I will make the distinction between the loose term APIs and specific React APIs.

</Aside>

When React 18 was released, it brought about APIs that allowed developers to finally use **some** of the concepts that were introduced with Fiber. You'll notice that I used the keyword **some** as it wouldn't be until React 19, specifically React 19.2 that developers would gain the remaining APIs that unlocked access to the full capability of Fiber.

APIs such as the following:

- Suspense
- startTransition (api) & useTransition
- useDeferredValue
- useOptimistic
- useFormStatus
- useActionState
- use (api)
- Activity
- View transitions (experimental)

These APIs are extensively documented within the React docs and there are also a number of tutorials that go over how each of them work. But let's speak on a few of these APIs and how they relate to React Fiber.

### Fibers importance with transitions

Earlier we stated that the move to Fiber was integral to the existence of transitions. To visualize this let's look at the following example using the stack reconciler.

Add some high priority work followed by some low priority work and see when tasks are get completed/rendered to the screen.

<AsyncReact_PriorityDemo />

Here we see that regardless of priority there is no difference in when items are rendered to the screen. In the event that we have a mix of components that are supposed to be high and low priority updates, we can see that rendering occurs in a certain order that follows a **last-in first-out principle**.

This brings about a challenge because we have a scenario in which we have a number of lower priority updates that are scheduled after the high priority updates. In the **stack reconciler world**, the higher priority updates will not be rendered until the lower priority updates are finished rendering. In essence we're unable to schedule the priority of rendering work.

Fiber fixed this problem as it introduced the concept of prioritization; it would schedule higher priority updates first then work on lower priority updates later. Let's take a look at the same example but with fiber enabled.

Again, add some high priority work followed by some low priority work and see when tasks are get completed/rendered to the screen.

<AsyncReact_PriorityDemo isFiber/>

It's different right!! Here we can see that all the high priority updates are rendered before the low priority updates. Moreover, if we're in the middle of rendering low priority updates and a high priority update comes in, the low priority work is paused, the high priority work is rendered, and then the low priority work resumes.

The APIs that enables this prioritization of state updates is **transitions**; specifically the startTransition API and the useTransition hook. These APIs allow us to mark a set of lower priority updates and let React know that the update within this function can be deferred until all the high priority work is complete.

### Fibers importance with Suspense

We've seen that Fiber introduced the concept interruptible renders; thereby allowing React to pause/resume renders, and completely throw away work that was yet to be committed to the DOM.

The switch to Fiber also has implications when we think about the Suspense component which allows developers to display fallback UI until it's children have finished loading. A component is said to be **suspended** when it throws a promise during the reconciliation phase. Rather than treating this as an error, React interprets the thrown promise as a signal that the component cannot finish rendering yet. The promise is caught by the nearest Suspense boundary, rendering of that subtree (ie the suspended component) is paused, and the fallback UI is rendered instead. Rendering of the sub-tree will only resume once the promise is resolved.

This can happen because fiber allows React to interrupt renders within the reconciliation phase. No DOM mutations have actually occurred at this point, so any partially rendered work can be safely abandoned.

We can see the Suspense component in action here:

<AsyncReact_SuspenseDemo />

Once we click the "Render Component" button the `Suspended component` begins rendering. During its render, it throws a promise that resolves after 3 seconds. While the promise is pending, the Suspense component catches it and displays the fallback UI ("Loading"). Once the promise resolves, rendering of `Suspended component` resumes and the final content is displayed.

There is a lot more intricacy to how Fiber enables this feature and although it's not directly mentioned, the mechanism is detailed in [Lin Clark's Talk](https://www.youtube.com/watch?v=ZCuYPiUIONs). The important thing here is that without the introduction of interruptible renders, the Suspense component would not exist.

## Async React

By this point, we've examined the role of the React reconciler, explored the architectural shift from the stack reconciler to React Fiber and seen how Fiber enabled the modern React APIs we have today—Suspense, transitions, optimistic updates, and actions.

What’s important to recognize is **how we got here**. We've seen that the rewrite of the reconciler laid the groundwork for async/concurrent rendering; however, the features that were built on top of it emerged **incrementally**, over multiple React releases.

As a result, these features continued to be documented, taught, and adopted **in-isolation**. **Suspense** was taught as a **loading mechanism**, **transitions** were framed as a **performance optimization**, **optimistic updates** were used for **UX enhancements**, and **actions** were concerned with **server form features**. While none of these descriptions were wrong, they missed the bigger picture.

These APIs are not separate ideas but rather they are **different expressions of the same underlying model** made possible by Fiber: coordinated, priority-aware, async/concurrent rendering.

While these features can be incrementally adopted, it results in a codebase that has a hybrid architecture that never fully benefits from Async React. The code works, but the mental model remains fragmented, and the system becomes harder to reason about as complexity grows.

### Think async first

To build modern React applications it requires us to shift our perspective on how we approach the architecture of said applications.

So what do we mean when we say build async first?

Async first means building applications where we use declarative tools to express user intent, loading, priority, and visual continuity. This allows React to treat rendering as a schedulable, and interruptible operation that React itself coordinates.

This means that we are defining a contract with the user; when the user acts immediately, the UI should respond immediately while some asynchronous work is done in the background. When the data is ready and no other higher priority work is to be done then we can show the completed state in a coordinated operation.

Ricky Hanlon modeled this in his talk [Async React](https://www.youtube.com/watch?v=B_2E96URooA) at React Conf 2025.

<AsyncReact_EventUpdate />

Taken together, this process looks something like our Instagram-like demo below. Let’s see how the interactions behave when we render the view, like/dislike a post, archive/unarchive a post, and switch tabs. Press **Render view** to begin!

<AsyncReact_InstagramDemo />

Did you try mixing up the interactions? How did the experience change when you archived a post and then switched tabs immediately?

This demo is built using async first principles! We're using a combination of optimistic states, transitions, suspense, and activity to craft this experience. You may have noticed that switching tabs was pretty instantaneous; however, when we archived a post and then switched tabs immediately, we **optimistically** switched to the **archive tab** and showed a loading indicator within the tab viewer. Since the render for the **archive tab** wasn't ready yet, React kept the experience within the **feed tab**. Once the async work resolved with it's data, React could fully switch to the **archive tab** showing all updated archived posts.

The important thing here is that all of this coordination is handled by React and we are just defining how these interactions should look. There is **no useEffect** within this demo that handles any of the async work! So how do we build async first components??

### An async first component

With async first components we can **assume** that when the component renders, it's rendering with all the data it requires.

We've seen that we can use suspense to coordinate the rendering between a loading fallback and a suspended component when data is not immediately available. But if we're making these assumptions and using suspense to allow React to do the coordination then what happens in the case of an error? What happens when that promise is rejected?

This is where error boundaries come into play. Similar to how the suspense component allows us to show a fallback when a promise is thrown, error boundaries allow us to show a fallback when an error thrown within a component. React is still handling the coordination but we are just providing the fallback UI and possibly a way to reset state to before the error occurred.

<Aside tag="FYI" title="Error Boundaries">
The implementation details of error boundaries have not moved forward into the functional component world, however, error boundaries become a crucial aspect of async React.

We can manually write error boundaries or we can opt to use libraries that have implemented the functionality for us. Libraries such as [react-error-boundary](https://www.npmjs.com/package/react-error-boundary) become a welcome addition in the world of async first.

</Aside>

We do make assumptions with this model but it's important to note that embedded within these assumptions is work that React itself coordinates. This pattern allow us to say that "async" is built **within** the rendering system of React rather than **around** it. So rather than asking "How do **I** coordinate asynchronous work over time?", this model shifts our perspective to ask "How should **React** coordinate this asynchronous work over time?".

So what does this look like in practice? Let's look at the example below to find out how we can build an async first React component.

```jsx
const UsersList = ({ userDataPromise }) => {
  const userList = use(userDataPromise);

  return (
    <div>
      {userList.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
};

const AsyncFirstDemo = ({ userDataPromise }) => {
  return (
    <ErrorBoundary fallback={<ErrorFallback />}>
      <Suspense fallback={<LoadingFallback />}>
        <UsersList userDataPromise={userDataPromise} />
      </Suspense>
    </ErrorBoundary>
  );
};
```

Do you remember our data fetching useEffect example from above? This looks a lot simpler right!?? We can see that an async first component brings the core principles of React to a world where data may not be immediately available. We describe to React how we want our components to look and function, and we let React coordinate the rest.

<Aside tag="FYI" title="Async First Demo">
You'll notice that in the example above we did not include the data fetching logic. This was intentional as the focus here was to show how we could build an async first component. However, we can fetch data in a number of ways; be it through server components, data fetching libraries, or even manually fetching data and passing down promises as props.

Libraries such as TanStack Query have embraced this model and provide hooks that return promises which can be used directly within async first components. However, we can of still write our own data fetching logic that returns a promise as well.

**Yes!** We keep saying **promise** here as we are not the ones that are writing the coordination! So whether the promise is pending, resolved, or rejected, it's React that is handling the coordination.

<Expanded>
So it's important that the data fetching logic live outside the component itself such the component can assume that when it renders, it's rendering with all the data it requires.

It looks something like this:

<AsyncReact_AsyncFirstDataFetchingDemo />

In side the `fetchUserData` function we are fetching data from an API endpoint and returning a promise. This promise is then passed down to the `UsersList` component as a prop. The `UsersList` component can then use the `use` api to unwrap the promise and render the data.

</Expanded>

</Aside>

## Component Systems and Routers with Async React

WOW!! This is a real paradigm shift in the way we think about building components. At first glance, it can feel like we’re trading simplicity for abstraction; adding new concepts like actions, Suspense/Error boundaries, transitions, and optimistic state just to achieve a more declarative, async-first model.

So it's natural to ask:

**Is this really how we’re supposed to be building applications now?** In short, yes but also no! It's more nuanced than that!

### Async first component libraries

Naturally this is where we would reach for component libraries or systems; A shared set of reusable, composable UI components which are already responsible for encoding design, behaviour, and accessibility decisions. These libraries/systems should also be able to participate within the async first model.

This is where **Action props** come into play! An action prop is just a prop that wraps the accepted synchronous/asynchronous function within a transition. This small change has large implications and it looks something like this:

```jsx
<Button action={saveUserAction}>Save</Button>
```

By accepting an action, the `Button` component can automatically reflect where it is within the rendering lifecycle. Be it pending states, disabled states, preventing duplicate interactions by default, or propagating errors to the nearest boundary; the action integrates these concerns into the component thereby allowing the consumer of the component to just declare what the button does.

We're already seeing this concept being added to React elements, specifically the form element. Instead on passing an `onSubmit` function to the form element, you can pass an `action` (ie sync/async function) to a form. This allows the children components to have access to the pending transition state or returned value from that action. Async first component libraries and systems are just an extension of this concept!

So in essence, async first component become **intent-driven**. They allow us to focus on declaring what the UI should do, rather than wiring up boilerplate for every async operation. We are essentially walking up the abstraction tree -- **Again**!

### Suspense enabled routers

Combining async-first components, and async component systems with suspense enabled routers builds on the notion of embracing an async first architecture within a React application.

**Suspense enabled routers** are routing systems designed to natively handle components that may suspend while loading data or code. These routers automatically wrap route rendering within suspense boundaries and show a defined fallback UI until the route is ready to render. We still have to define the fallback UI for the page, be it a skeleton or loading spinner, but then the router handles the rest. Moreover, similar to how we can define a fallback UI for the suspense boundaries, suspense enabled routers also allow us to define an error fallback UI in the event that the suspended component cannot be resolved.

Using suspense enabled routers also means that we are opting into navigation and data fetching solutions that are using React’s async rendering strategy. This means that navigation's are wrapped within transitions and thus considered low-priority updates. Here React **keeps the current UI responsive and visible** while the next route is being prepared. This becomes important when route components suspend for data or code, because the transition prevent unnecessary loading UI.

This looks something like this! Click through the tabs to see how the router handles async components.

<AsyncReact_TabsDemo/>

We can see that clicking on the Explore tab reveals a pending state within the navigation bar while the router prepares the component in the background. Once the component/route is ready, the router switches to the Explore tab. The important thing to note here is that the current UI remains visible and interactive while the next route is being prepared. So if we were to switch to the Explore tab and then quickly switch to the Recommended tab, the router would cancel the preparation of the Explore route and begin preparing the Recommended route instead. This creates a seamless experience when navigating through the application and updates aren't jarring to the user.

<Aside tag="FYI" title="Where can we find suspense enabled routers">
These mechanisms are exposed through the routers APIs and can differ in implementation but the core logic that enables us to hook into suspense and transitions remains the same.

Frameworks like NextJS App router support a suspense enabled router solution. These routers allow us to define a fallback UI for both suspense and error boundaries within the routing API and the suspended components are automatically handled. Since NextJS has a file-based routing system, we just define a `loading.tsx` and `error.tsx` to enable fallbacks for route pages to be visible.

Libraries such as React Router V7 framework/data mode also support a suspense enabled routing solution; however, this library is not a pure suspense driven router. Here all navigations are wrapped within transitions and thus considered low priority updates. The feature that this router lacks is automatically wrapping all components defined within the router within a suspense boundary. It is something to be aware of as we transition into the async first world and we can still manually wrap our routes within a suspense boundary to have an appropriate fallback UI shown.

</Aside>

It is pretty fascinating how all these pieces come together right!?? Async first components, async first component libraries/systems, and suspense enabled routers all work in tandem to allow us to build React applications that embrace **async** as the default.

## Wrapping up

WOW!! Async React, it only took 10 years but it's here!! This is an incredible feat of engineering and also a huge mindset shift in how we should build React applications today.

But through our journey we discovered that we didn't get to Async React by accident. We found that the change in the underlying mechanism of the React reconciler, the shift from the stack reconciler to React Fiber, enabled the ability to schedule, interrupt, prioritize, and abandon renders before any updates were committed to the DOM. We further uncovered the role Fiber played in the mechanisms behind features like suspense and transitions.

This then opened up the conversation around Async React and how the APIs released within React 18/19 were not isolated ideas but rather an expression of an underlying mental model made possible by Fiber.

So, what is **Async React**?!??

We found that it’s a **way of thinking and building with React that embraces async as the default**, rather than treating it as an edge case or an afterthought. Here **React** does the coordination of when and how UI updates happen instead of forcing components to manage these dependencies themselves. This allows components to assume that data is available, suspend when it isn’t, and resume automatically without manual loading or lifecycle orchestration. So we as devs write more declarative code and allow React to handle the complexity of coordinating data fetching, rendering, and user interactions in a responsive, non-blocking way.

We extended this mental model by writing **async-first components** that explicitly wrapped low-priority updates within transitions. Therefore, allowing React to keep urgent interactions responsive while preparing non-critical UI updates in the background. We saw the benefits here but naturally this posed a follow up question: **should all state updates be wrapped within transitions?**

In practice, **no**. Transitions are specifically meant to mark **non-urgent updates**. Updates such as responding to user input, typing, or pointer feedback, should remain synchronous so that the interface stays immediately responsive. Wrapping all state updates within transitions would blur this distinction and could delay updates the user expects to see immediately.

Similar to how we use semantic HTML tags, we have to be intentional about when we wrap state updates within transitions. So naturally, we should develop a semantic language around when to and when not to use transitions.

This also extends to **async first component libraries**! You'll notice we used the keyword **"should"** when describing the participation of a component library within the async first model. Here, we are **not** suggesting that `action props` replace the `onClick` property exposed by a component within a library. Rather, `action props` should live alongside the `onClick` property within these components. This gives the consumers the ability to choose between strictly synchronous high priority updates or asynchronous low priority updates that reflect pending, disabled, and errors states. Naturally semantics should evolve here as well!

Finally, we looked at **suspense-enabled routers**. We found that these are routing systems designed to natively support components that may suspend while loading data or code. These routers would automatically render routes within Suspense boundaries, and show a defined fallback UI until the route was ready. We would still need to define what the fallback loading and error UI would look like, but the router would handle when they appear. We also found that these routers wrapped navigation's within transitions to allow React to keep the current UI responsive and visible while the next route was being prepared in the background. This creates a seamless experience when navigating through the application and updates aren't jarring to the user.

WOW! The even more incredible thing is that some of these concepts extend beyond React web applications. As we said, the React reconciler is platform agnostic so it means that some of these concepts can be applied to other renderers such as React Native. This opens up a whole new world of building async first applications across different platforms!

So Async React! What do we think? I was talking with a colleague recently about this topic and we wondered if it would have been easier if we got these APIs all at once instead of having them be released incrementally. Would it have made understanding the story of Async React easier?

I'm not sure!! But I do think it's a cool story and we should continue conversations around Async React now that we have it all! We should also keep these concepts in mind as we build with React and architect new experiences. I'm going to leave you with a few questions to ponder: What does Async React mean for the library authors that are building the hooks, components, and tools for other developers to use? How do we expect these libraries to participate within the async first model? After all, there are some libraries that have already started this journey but there still remains a lot of unanswered questions.

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article?? Here's a fun little exercise for you to try out! 👀

<AsyncReact_Exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>React</category>
        </item>
        <item>
            <title><![CDATA[From Fiber to Async React]]></title>
            <link>https://www.nonsoo.com/posts/async-react</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/async-react</guid>
            <pubDate>Thu, 15 Jan 2026 00:17:35 GMT</pubDate>
            <description><![CDATA[The re-architecture of React's rendering algorithm represents a fundamental shift in how we should build react apps today. In this article, we trace that journey, showing how this algorithm's ability to abandon, interrupt, and prioritize renders underpins modern features like Activity, Suspense, and Transitions. We further introduce “Async React” as a new mental model and show how we can write and use async-first components, libraries, and suspense-enabled routers. Let’s write more declarative code, embrace async-first as the default and let React handle the rest.]]></description>
            <content:encoded><![CDATA[
It been some time since React 19 was released and since then we've seen new api's, hooks, and components that we can add to our apps. Some may argue that these are welcome changes while others may argue that these additions are cool but what's the point?

Let's pose the following question to begin! How would we go about doing data fetching or any async operation within React? Yes, of course we can reach for data-fetching/async libraries such as TanStack Query, swr, etc but let's pretend that we didn't have access to these libraries. How would we go about doing this?

The following code snippet may look familiar!

```jsx
const UsersList = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchUsers = async () => {
      setLoading(true);
      setError(null);

      try {
        const response = await fetch("/api/users");

        if (!response.ok) {
          throw new Error("Failed to fetch users");
        }

        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchUsers();
  }, []);
};
```

Traditionally, we would often reach for a `useEffect` to handle any asynchronous work (data fetching included) within our React applications. Here we've setup a component that calls the `fetchUsers` function when the component gets mounted to the DOM. We are then setting the data, loading, and error states appropriately such that we can display the correct UI to the user.

This approach works, but as many within the React community and the core React team have noted, this approach has many shortcomings and is not the advised method of handling asynchronous work with React.

Truthfully, React has always dealt with asynchronous work, even if it didn’t explicitly model it. Data fetching, code splitting, user input, animations, and navigation all happen asynchronously, yet for much of React’s history these concerns lived **around** the rendering system rather than **within** it.

As we've seen this meant that we were responsible for stitching together loading states, effects, and imperative updates so that we could keep the UI coherent while asynchronous work was completed. But should that be the responsibility of the application developer or should that responsibility be put elsewhere?

Let's consider the following; What would a React codebase look like if asynchronous work lived **within** the rendering system rather than **around** it? How would it change the way we approach building components, component systems and eventual whole applications?

The release of React 19 brought about the completion story of **"Async React"**, a term we'll unwrap throughout this article. We'll look at how "Async React" solves the coordination problem between UI and async work and we will attempt to answer the questions we posed above. We'll also look at new questions; Knowing that Async React is here, how do we expect React Library authors to build and compose the tools they expose to application developers?

It's a whole new world for developers in terms of how we structure our React applications and these changes can expand the types of experiences we can create. Throughout the article, we'll do a lot of deep dives, so these are just a few things to keep in mind while we explore the modern way of building React applications.

## The React Reconciler

You'll often notice that two important packages are installed when you create a React web app; **React** and **React-dom**. The React package is the library that allows us to describe UI as a function of some state. We often see this represented as the following equation **UI = f(state)** and we use JSX as the method to represent it.

Great! So where does `react-dom` come into play?

React-dom is the package that contains the **React reconciler** and **renderer for the web**. The reconciler is the engine responsible for comparing render outputs over time, scheduling work, and determining the minimal set of updates needed to be applied to the host platform<ToolTip>I use the term **Host platform** here because the React reconciler is platform agnostic. This means that it can be used with different platforms like the Web, mobile, different renderers, etc.</ToolTip>. The renderer then takes the output from the reconciler and applies it to the host platform; in this case the DOM.

The reconciler becomes important when speaking about Async React and how the new APIs were made possible. During [React conf 2017](https://www.youtube.com/watch?v=ZCuYPiUIONs) it was revealed that the React reconciler was rebuilt from the ground up as we went from what was known as the **stack reconciler** to **React Fiber**.

### Stack Reconciler

The stack reconciler was reconciliation engine that was used in the earlier versions of React up until React 16. It was designed to closely mirror how JavaScript executes function calls; therefore it relied directly on the call stack to traverse and render the component tree.

When a render was triggered—typically by a change in state—React would start at the root and recursively walk the component tree from top to bottom calling each components render function, reconciling the diff and then committing the result. This meant that once reconciliation/render began, React was required to complete the entire process before yielding control back to the browser.

We can see this in the following render example below. Press the **"start render"** button and see how rendering is taking place to update the count value within the dashboard component.

<AsyncReact_StackReconcilerDemo />

This approach was entirely synchronous and non-interruptible. All rendering work happened in a single pass, and all updates were treated with the same priority. While this made the system straightforward and predictable, it also meant that long renders could block the main thread, delaying user input and causing visible stutters in complex applications.

Considering the limitations of the stack reconciler, could we imagine a world where improvements could be made?

**POP Quiz!**
<AsyncReact_StackReconcilerTrueOrFalse />

### React Fiber

Enter **React Fiber**; a complete rewrite of React’s reconciler which was introduced in React 16 to address the limitations of the stack-based approach. Instead of implementing rendering in one single uninterrupted pass, Fiber would implement its own internal representation of the component tree--a Fiber Tree--and its own scheduling model.

In Fiber, each component is represented as a unit of work (a fiber) which can be processed independently. Rendering is broken into small, incremental steps, allowing React to pause work, yield to the browser <ToolTip>**Cooperative Scheduling** -- By yielding control back to the browser, React ensures that animations and interactions are not blocked, improving the overall user experience)</ToolTip>, and resume later. This means that Fiber splits the **reconciliation/rendering phase** and **commit phase** into two independent processes.

<Aside tag="FYI" title="The Fiber Node">
A Fiber node is a lightweight object that describes the metadata associated with a component. Importantly, each Fiber contains pointers that link it to its parent, child, and sibling components. A very contrived fiber node can be seen below however the full implementation can be viewed within the react codebase.

<AsyncReact_FiberNodeAside />

Since each Fiber represents a discrete unit of work, React can process the tree one unit at a time, rather than relying on a recursive function call that must run to completion. Between units, React can check whether it should continue rendering or yield control back to the browser. If rendering needs to pause, React simply stops traversal, retains its place in the Fiber tree, and yields. When work resumes, React continues from the next Fiber as if nothing happened.

This process is known as time slicing, and it is a direct consequence of modeling rendering work as a JavaScript object.

</Aside>

During the reconciliation/rendering (now referred to as the reconciliation phase), a list of all changes to be rendered in the UI is generated but does not get committed to the DOM. Rather, the changes are scheduled to be committed in the next phase. The **commit phase**, is when these changes are committed to the DOM.

The important thing to note here is that the **reconciliation phase** can be interrupted, paused/resumed, and discarded completely. The **commit phase** **cannot** be interrupted; therefore once the commit phase starts, it must finish before any other work can be done.

**POP Quiz!**
<AsyncReact_FiberTrueOrFalse />

Since the **reconciliation phase** can be interrupted, it suggests that the two independent pieces of work can be within the **reconciliation phase** and then progress into the **commit phase** out of order. This allows Fiber to introduce the concept of prioritization when speaking about showing render updates within the DOM.

Fiber allows React to schedule high-priority updates first while deferring lower-priority updates, thereby improving both perceived performance and user experience. We can imagine that typing into an input is more urgent than rendering data that just finished loading in the background. So why not defer rendering of the data so that we can show the state of the input field immediately. The rendering of the data will just happen after the user is done typing. This is what we mean by improved perceived performance.

So what are the priorities for Fiber? They are as follows:

- Synchronous Work (involves clicking/typing -- works like the stack reconciler)
- Task Work
- Animation (started by **`requestAnimationFrame()`** )
- high priority
- low priority
- off-screen (anything not currently in view but would be nice to have rendered in case it gets shown)

Understanding these priority groups will be important later on when we speak of the APIs, hooks, and components that were introduced in React 18 and 19. But the core thing here is that without the move to Fiber the concept of **Async React** would not be possible.

<Aside tag="FYI" title="More on the reconciler">
For an in-depth look at the reconciler and React fiber, checkout the [Lin Clark's Talk, A Cartoon Intro to Fiber](https://www.youtube.com/watch?v=ZCuYPiUIONs) or [Brandon's talk, Algebraic effects, Fibers, Coroutines Oh my](https://www.youtube.com/watch?v=7GcrT0SBSnI)!

You can also look into these browser APIs which are pertinent to the fiber reconciler: [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback), and [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame).

</Aside>

## Modern React Features

React Fiber was such a monumental feat of engineering as it introduced the ability to have interruptible renders, cooperative scheduling, prioritization, and so much more. With these concepts introduced, we could begin to imagine a new world of building React applications. However, the core entities that were missing from the Fiber release were the APIs that would allow developers to hook into this new way of building.

<Aside tag="FYI" title="APIs definition">
To note, I use the term APIs loosely here to refer to hooks, functions, and components that are available by React. However, React has a formal definition of **API** which refers to the functions made available by the React package.

Throughout the article I will make the distinction between the loose term APIs and specific React APIs.

</Aside>

When React 18 was released, it brought about APIs that allowed developers to finally use **some** of the concepts that were introduced with Fiber. You'll notice that I used the keyword **some** as it wouldn't be until React 19, specifically React 19.2 that developers would gain the remaining APIs that unlocked access to the full capability of Fiber.

APIs such as the following:

- Suspense
- startTransition (api) & useTransition
- useDeferredValue
- useOptimistic
- useFormStatus
- useActionState
- use (api)
- Activity
- View transitions (experimental)

These APIs are extensively documented within the React docs and there are also a number of tutorials that go over how each of them work. But let's speak on a few of these APIs and how they relate to React Fiber.

### Fibers importance with transitions

Earlier we stated that the move to Fiber was integral to the existence of transitions. To visualize this let's look at the following example using the stack reconciler.

Add some high priority work followed by some low priority work and see when tasks are get completed/rendered to the screen.

<AsyncReact_PriorityDemo />

Here we see that regardless of priority there is no difference in when items are rendered to the screen. In the event that we have a mix of components that are supposed to be high and low priority updates, we can see that rendering occurs in a certain order that follows a **last-in first-out principle**.

This brings about a challenge because we have a scenario in which we have a number of lower priority updates that are scheduled after the high priority updates. In the **stack reconciler world**, the higher priority updates will not be rendered until the lower priority updates are finished rendering. In essence we're unable to schedule the priority of rendering work.

Fiber fixed this problem as it introduced the concept of prioritization; it would schedule higher priority updates first then work on lower priority updates later. Let's take a look at the same example but with fiber enabled.

Again, add some high priority work followed by some low priority work and see when tasks are get completed/rendered to the screen.

<AsyncReact_PriorityDemo isFiber/>

It's different right!! Here we can see that all the high priority updates are rendered before the low priority updates. Moreover, if we're in the middle of rendering low priority updates and a high priority update comes in, the low priority work is paused, the high priority work is rendered, and then the low priority work resumes.

The APIs that enables this prioritization of state updates is **transitions**; specifically the startTransition API and the useTransition hook. These APIs allow us to mark a set of lower priority updates and let React know that the update within this function can be deferred until all the high priority work is complete.

### Fibers importance with Suspense

We've seen that Fiber introduced the concept interruptible renders; thereby allowing React to pause/resume renders, and completely throw away work that was yet to be committed to the DOM.

The switch to Fiber also has implications when we think about the Suspense component which allows developers to display fallback UI until it's children have finished loading. A component is said to be **suspended** when it throws a promise during the reconciliation phase. Rather than treating this as an error, React interprets the thrown promise as a signal that the component cannot finish rendering yet. The promise is caught by the nearest Suspense boundary, rendering of that subtree (ie the suspended component) is paused, and the fallback UI is rendered instead. Rendering of the sub-tree will only resume once the promise is resolved.

This can happen because fiber allows React to interrupt renders within the reconciliation phase. No DOM mutations have actually occurred at this point, so any partially rendered work can be safely abandoned.

We can see the Suspense component in action here:

<AsyncReact_SuspenseDemo />

Once we click the "Render Component" button the `Suspended component` begins rendering. During its render, it throws a promise that resolves after 3 seconds. While the promise is pending, the Suspense component catches it and displays the fallback UI ("Loading"). Once the promise resolves, rendering of `Suspended component` resumes and the final content is displayed.

There is a lot more intricacy to how Fiber enables this feature and although it's not directly mentioned, the mechanism is detailed in [Lin Clark's Talk](https://www.youtube.com/watch?v=ZCuYPiUIONs). The important thing here is that without the introduction of interruptible renders, the Suspense component would not exist.

## Async React

By this point, we've examined the role of the React reconciler, explored the architectural shift from the stack reconciler to React Fiber and seen how Fiber enabled the modern React APIs we have today—Suspense, transitions, optimistic updates, and actions.

What’s important to recognize is **how we got here**. We've seen that the rewrite of the reconciler laid the groundwork for async/concurrent rendering; however, the features that were built on top of it emerged **incrementally**, over multiple React releases.

As a result, these features continued to be documented, taught, and adopted **in-isolation**. **Suspense** was taught as a **loading mechanism**, **transitions** were framed as a **performance optimization**, **optimistic updates** were used for **UX enhancements**, and **actions** were concerned with **server form features**. While none of these descriptions were wrong, they missed the bigger picture.

These APIs are not separate ideas but rather they are **different expressions of the same underlying model** made possible by Fiber: coordinated, priority-aware, async/concurrent rendering.

While these features can be incrementally adopted, it results in a codebase that has a hybrid architecture that never fully benefits from Async React. The code works, but the mental model remains fragmented, and the system becomes harder to reason about as complexity grows.

### Think async first

To build modern React applications it requires us to shift our perspective on how we approach the architecture of said applications.

So what do we mean when we say build async first?

Async first means building applications where we use declarative tools to express user intent, loading, priority, and visual continuity. This allows React to treat rendering as a schedulable, and interruptible operation that React itself coordinates.

This means that we are defining a contract with the user; when the user acts immediately, the UI should respond immediately while some asynchronous work is done in the background. When the data is ready and no other higher priority work is to be done then we can show the completed state in a coordinated operation.

Ricky Hanlon modeled this in his talk [Async React](https://www.youtube.com/watch?v=B_2E96URooA) at React Conf 2025.

<AsyncReact_EventUpdate />

Taken together, this process looks something like our Instagram-like demo below. Let’s see how the interactions behave when we render the view, like/dislike a post, archive/unarchive a post, and switch tabs. Press **Render view** to begin!

<AsyncReact_InstagramDemo />

Did you try mixing up the interactions? How did the experience change when you archived a post and then switched tabs immediately?

This demo is built using async first principles! We're using a combination of optimistic states, transitions, suspense, and activity to craft this experience. You may have noticed that switching tabs was pretty instantaneous; however, when we archived a post and then switched tabs immediately, we **optimistically** switched to the **archive tab** and showed a loading indicator within the tab viewer. Since the render for the **archive tab** wasn't ready yet, React kept the experience within the **feed tab**. Once the async work resolved with it's data, React could fully switch to the **archive tab** showing all updated archived posts.

The important thing here is that all of this coordination is handled by React and we are just defining how these interactions should look. There is **no useEffect** within this demo that handles any of the async work! So how do we build async first components??

### An async first component

With async first components we can **assume** that when the component renders, it's rendering with all the data it requires.

We've seen that we can use suspense to coordinate the rendering between a loading fallback and a suspended component when data is not immediately available. But if we're making these assumptions and using suspense to allow React to do the coordination then what happens in the case of an error? What happens when that promise is rejected?

This is where error boundaries come into play. Similar to how the suspense component allows us to show a fallback when a promise is thrown, error boundaries allow us to show a fallback when an error thrown within a component. React is still handling the coordination but we are just providing the fallback UI and possibly a way to reset state to before the error occurred.

<Aside tag="FYI" title="Error Boundaries">
The implementation details of error boundaries have not moved forward into the functional component world, however, error boundaries become a crucial aspect of async React.

We can manually write error boundaries or we can opt to use libraries that have implemented the functionality for us. Libraries such as [react-error-boundary](https://www.npmjs.com/package/react-error-boundary) become a welcome addition in the world of async first.

</Aside>

We do make assumptions with this model but it's important to note that embedded within these assumptions is work that React itself coordinates. This pattern allow us to say that "async" is built **within** the rendering system of React rather than **around** it. So rather than asking "How do **I** coordinate asynchronous work over time?", this model shifts our perspective to ask "How should **React** coordinate this asynchronous work over time?".

So what does this look like in practice? Let's look at the example below to find out how we can build an async first React component.

```jsx
const UsersList = ({ userDataPromise }) => {
  const userList = use(userDataPromise);

  return (
    <div>
      {userList.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
};

const AsyncFirstDemo = ({ userDataPromise }) => {
  return (
    <ErrorBoundary fallback={<ErrorFallback />}>
      <Suspense fallback={<LoadingFallback />}>
        <UsersList userDataPromise={userDataPromise} />
      </Suspense>
    </ErrorBoundary>
  );
};
```

Do you remember our data fetching useEffect example from above? This looks a lot simpler right!?? We can see that an async first component brings the core principles of React to a world where data may not be immediately available. We describe to React how we want our components to look and function, and we let React coordinate the rest.

<Aside tag="FYI" title="Async First Demo">
You'll notice that in the example above we did not include the data fetching logic. This was intentional as the focus here was to show how we could build an async first component. However, we can fetch data in a number of ways; be it through server components, data fetching libraries, or even manually fetching data and passing down promises as props.

Libraries such as TanStack Query have embraced this model and provide hooks that return promises which can be used directly within async first components. However, we can of still write our own data fetching logic that returns a promise as well.

**Yes!** We keep saying **promise** here as we are not the ones that are writing the coordination! So whether the promise is pending, resolved, or rejected, it's React that is handling the coordination.

<Expanded>
So it's important that the data fetching logic live outside the component itself such the component can assume that when it renders, it's rendering with all the data it requires.

It looks something like this:

<AsyncReact_AsyncFirstDataFetchingDemo />

In side the `fetchUserData` function we are fetching data from an API endpoint and returning a promise. This promise is then passed down to the `UsersList` component as a prop. The `UsersList` component can then use the `use` api to unwrap the promise and render the data.

</Expanded>

</Aside>

## Component Systems and Routers with Async React

WOW!! This is a real paradigm shift in the way we think about building components. At first glance, it can feel like we’re trading simplicity for abstraction; adding new concepts like actions, Suspense/Error boundaries, transitions, and optimistic state just to achieve a more declarative, async-first model.

So it's natural to ask:

**Is this really how we’re supposed to be building applications now?** In short, yes but also no! It's more nuanced than that!

### Async first component libraries

Naturally this is where we would reach for component libraries or systems; A shared set of reusable, composable UI components which are already responsible for encoding design, behaviour, and accessibility decisions. These libraries/systems should also be able to participate within the async first model.

This is where **Action props** come into play! An action prop is just a prop that wraps the accepted synchronous/asynchronous function within a transition. This small change has large implications and it looks something like this:

```jsx
<Button action={saveUserAction}>Save</Button>
```

By accepting an action, the `Button` component can automatically reflect where it is within the rendering lifecycle. Be it pending states, disabled states, preventing duplicate interactions by default, or propagating errors to the nearest boundary; the action integrates these concerns into the component thereby allowing the consumer of the component to just declare what the button does.

We're already seeing this concept being added to React elements, specifically the form element. Instead on passing an `onSubmit` function to the form element, you can pass an `action` (ie sync/async function) to a form. This allows the children components to have access to the pending transition state or returned value from that action. Async first component libraries and systems are just an extension of this concept!

So in essence, async first component become **intent-driven**. They allow us to focus on declaring what the UI should do, rather than wiring up boilerplate for every async operation. We are essentially walking up the abstraction tree -- **Again**!

### Suspense enabled routers

Combining async-first components, and async component systems with suspense enabled routers builds on the notion of embracing an async first architecture within a React application.

**Suspense enabled routers** are routing systems designed to natively handle components that may suspend while loading data or code. These routers automatically wrap route rendering within suspense boundaries and show a defined fallback UI until the route is ready to render. We still have to define the fallback UI for the page, be it a skeleton or loading spinner, but then the router handles the rest. Moreover, similar to how we can define a fallback UI for the suspense boundaries, suspense enabled routers also allow us to define an error fallback UI in the event that the suspended component cannot be resolved.

Using suspense enabled routers also means that we are opting into navigation and data fetching solutions that are using React’s async rendering strategy. This means that navigation's are wrapped within transitions and thus considered low-priority updates. Here React **keeps the current UI responsive and visible** while the next route is being prepared. This becomes important when route components suspend for data or code, because the transition prevent unnecessary loading UI.

This looks something like this! Click through the tabs to see how the router handles async components.

<AsyncReact_TabsDemo/>

We can see that clicking on the Explore tab reveals a pending state within the navigation bar while the router prepares the component in the background. Once the component/route is ready, the router switches to the Explore tab. The important thing to note here is that the current UI remains visible and interactive while the next route is being prepared. So if we were to switch to the Explore tab and then quickly switch to the Recommended tab, the router would cancel the preparation of the Explore route and begin preparing the Recommended route instead. This creates a seamless experience when navigating through the application and updates aren't jarring to the user.

<Aside tag="FYI" title="Where can we find suspense enabled routers">
These mechanisms are exposed through the routers APIs and can differ in implementation but the core logic that enables us to hook into suspense and transitions remains the same.

Frameworks like NextJS App router support a suspense enabled router solution. These routers allow us to define a fallback UI for both suspense and error boundaries within the routing API and the suspended components are automatically handled. Since NextJS has a file-based routing system, we just define a `loading.tsx` and `error.tsx` to enable fallbacks for route pages to be visible.

Libraries such as React Router V7 framework/data mode also support a suspense enabled routing solution; however, this library is not a pure suspense driven router. Here all navigations are wrapped within transitions and thus considered low priority updates. The feature that this router lacks is automatically wrapping all components defined within the router within a suspense boundary. It is something to be aware of as we transition into the async first world and we can still manually wrap our routes within a suspense boundary to have an appropriate fallback UI shown.

</Aside>

It is pretty fascinating how all these pieces come together right!?? Async first components, async first component libraries/systems, and suspense enabled routers all work in tandem to allow us to build React applications that embrace **async** as the default.

## Wrapping up

WOW!! Async React, it only took 10 years but it's here!! This is an incredible feat of engineering and also a huge mindset shift in how we should build React applications today.

But through our journey we discovered that we didn't get to Async React by accident. We found that the change in the underlying mechanism of the React reconciler, the shift from the stack reconciler to React Fiber, enabled the ability to schedule, interrupt, prioritize, and abandon renders before any updates were committed to the DOM. We further uncovered the role Fiber played in the mechanisms behind features like suspense and transitions.

This then opened up the conversation around Async React and how the APIs released within React 18/19 were not isolated ideas but rather an expression of an underlying mental model made possible by Fiber.

So, what is **Async React**?!??

We found that it’s a **way of thinking and building with React that embraces async as the default**, rather than treating it as an edge case or an afterthought. Here **React** does the coordination of when and how UI updates happen instead of forcing components to manage these dependencies themselves. This allows components to assume that data is available, suspend when it isn’t, and resume automatically without manual loading or lifecycle orchestration. So we as devs write more declarative code and allow React to handle the complexity of coordinating data fetching, rendering, and user interactions in a responsive, non-blocking way.

We extended this mental model by writing **async-first components** that explicitly wrapped low-priority updates within transitions. Therefore, allowing React to keep urgent interactions responsive while preparing non-critical UI updates in the background. We saw the benefits here but naturally this posed a follow up question: **should all state updates be wrapped within transitions?**

In practice, **no**. Transitions are specifically meant to mark **non-urgent updates**. Updates such as responding to user input, typing, or pointer feedback, should remain synchronous so that the interface stays immediately responsive. Wrapping all state updates within transitions would blur this distinction and could delay updates the user expects to see immediately.

Similar to how we use semantic HTML tags, we have to be intentional about when we wrap state updates within transitions. So naturally, we should develop a semantic language around when to and when not to use transitions.

This also extends to **async first component libraries**! You'll notice we used the keyword **"should"** when describing the participation of a component library within the async first model. Here, we are **not** suggesting that `action props` replace the `onClick` property exposed by a component within a library. Rather, `action props` should live alongside the `onClick` property within these components. This gives the consumers the ability to choose between strictly synchronous high priority updates or asynchronous low priority updates that reflect pending, disabled, and errors states. Naturally semantics should evolve here as well!

Finally, we looked at **suspense-enabled routers**. We found that these are routing systems designed to natively support components that may suspend while loading data or code. These routers would automatically render routes within Suspense boundaries, and show a defined fallback UI until the route was ready. We would still need to define what the fallback loading and error UI would look like, but the router would handle when they appear. We also found that these routers wrapped navigation's within transitions to allow React to keep the current UI responsive and visible while the next route was being prepared in the background. This creates a seamless experience when navigating through the application and updates aren't jarring to the user.

WOW! The even more incredible thing is that some of these concepts extend beyond React web applications. As we said, the React reconciler is platform agnostic so it means that some of these concepts can be applied to other renderers such as React Native. This opens up a whole new world of building async first applications across different platforms!

So Async React! What do we think? I was talking with a colleague recently about this topic and we wondered if it would have been easier if we got these APIs all at once instead of having them be released incrementally. Would it have made understanding the story of Async React easier?

I'm not sure!! But I do think it's a cool story and we should continue conversations around Async React now that we have it all! We should also keep these concepts in mind as we build with React and architect new experiences. I'm going to leave you with a few questions to ponder: What does Async React mean for the library authors that are building the hooks, components, and tools for other developers to use? How do we expect these libraries to participate within the async first model? After all, there are some libraries that have already started this journey but there still remains a lot of unanswered questions.

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article?? Here's a fun little exercise for you to try out! 👀

<AsyncReact_Exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[Monitor your Aerospike Database with Datadog]]></title>
            <link>https://www.nonsoo.com/posts/datadog-aerospike</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/datadog-aerospike</guid>
            <pubDate>Thu, 08 Aug 2024 01:52:55 GMT</pubDate>
            <description><![CDATA[Going over the Aerospike integration with Datadog]]></description>
            <content:encoded><![CDATA[
The Aerospike Database is an in-memory open-source distributed key-value NoSQL database that enables businesses to act in real-time and cost-effectively scale their data. Unlike traditional NoSQL databases, Aerospike provides predictable performance, scales to process petabytes of data, and uses a cross-datacenter replication technique to create a globally distributed real-time database.

Our new Aerospike integration provides vital KPIs which can help your team monitor the health and efficiency of the database. Alongside vital KPIs, this integration offers a variety of ready-made dashboards that allow your team to visualize vital metrics and gain further insights into the performance of the database.

Throughout this article, we'll explore how your team can use this integration to uncover the answers to critical questions such as:

1. How can we ensure the high availability and performance of our aerospike database globally?
2. How can we visualize the health and efficacy of our Aerospike database?

## Maintaining high availability & performance of aerospike databases

The Aerospike database system is unique in that it uses a technique known as cross-datacenter replication (XDR) to create globally distributed real-time databases. This is accomplished by the asynchronous replication of data between two or more clusters located at different geographically distributed sites. As such, it may be useful to have access to dashboards that show vital indicators of the high availability & performance of your Aerospike database globally.

Our new integration provides these dashboards and metrics, thus giving your team the confidence that the database is highly available. Metrics such as the **Aerospike XDR ship success** -- an indicator of the number of records that have been successfully shipped to remote Aerospike clusters -- and the **Aerospike XDR global last ship time** -- an indicator for the last ship time for XDR across the cluster -- become available in dashboards and can be monitored across time. The dashboards additionally allow you to track metrics like **Aerospike XDR lag** and **Aerospike namespace balance** so as to have greater insight into the performance of the database and its ability to distribute partitions to all nodes globally.

To be up-to-date on current issues within your system, our integration also allows you to create monitors that alert you when critical KPIs fail to meet performance standards. Moreover, when these monitors notify you of unusual activity, you can investigate the metrics and take further action to determine the root cause alongside assessing possible remediation strategies. For example, you can set up monitors and alerts that track the **XDR lag time** so your team can be notified when the **XDR lag time** has consistently exceeded a few seconds.

**Consider the following:**

Here we have three different snapshots of the XDR lag time for a node in our Aerospike database. Let's see what happens when we set all three lag times to a number greater than 5 seconds.

<Datadog_Lagtime />

As we can see, when all three lag times are greater than 5 seconds, we are notified by an alert. This alert may indicate network connectivity issues or other errors at a destination cluster. Your team can then investigate further and take action to remediate the issue.

## Visualizing the health of your Aerospike Database

Alongside the metrics we previously mentioned, our integration gathers metrics that can provide an overview of the health and efficacy of your system. These metrics can be visualized through summarized dashboards. For example, metrics such as the **Aerospike client connections** and **Aerospike client connections opened** can give your team insight into whether clients can establish a connection with a node in your database.

Additionally, our integration can help you to reconstruct a detailed picture of the state of your system by providing dashboards that give you insight into system resources. This is especially important given that the Aerospike database can act as an in-memory database -- storing data fully in RAM (random-access-memory). Knowing this, it may become useful to have metrics that monitor RAM usage and performance. Our integration allows your team to access and view metrics such as **system free memory**, **heap efficiency**, and **Memory data bytes**, which can help evaluate whether your system has sufficient resources to handle current workloads.

## Getting started with the Aerospike integration

With comprehensive metrics and out-of-the-box dashboards, Datadog provides deep insights into the health and performance of your Aerospike database. As we've discussed, monitors and alerts allow your team to respond rapidly to abnormal metrics so as to ensure your database's health and availability. From a broader scope, Datadog provides full visibility into your infrastructure and network, thereby allowing your team to have confidence that applications are healthy, performant, and available.

Check out [our documentation](https://docs.datadoghq.com) to start monitoring your next application. If you’re new to Datadog, you can sign up for a 14-day free trial.

## Key takeaway questions

<Datadog_Exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>programming</category>
        </item>
        <item>
            <title><![CDATA[The scary relief of React Server Components and actions]]></title>
            <link>https://www.nonsoo.com/posts/rsc</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/rsc</guid>
            <pubDate>Thu, 01 Aug 2024 19:42:50 GMT</pubDate>
            <content:encoded><![CDATA[
It's been a couple of years since the React team started conversations around **React Server Components** (RSC) and with React 19 on the way, it's a good time to become familiar with this new paradigm of building React applications.

New paradigm?!??? Yes, indeed a new paradigm! Ever since the [**request for comment**](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md) for RSCs, there has been a lot of confusion as to what react server components actually are. In short, RSCs are a way to render react components exclusively on the server. But what does that mean? How does it work? What are the benefits? And how do RSCs fit together with Server Side Rendering?

I've spent the last year experimenting with RSCs, both on the concept level and on the framework level and I wanted to share a piece of what I've learnt. In my opinion, RSCs are truly something to be excited about as they enable new user experiences while also improving the overall performance of an application! **They are soooooo cool!!**

Throughout this article we'll deep dive into what React Server components mean, we'll answer the questions we posed above, and explore some future possibilities as a result of moving an application to RSCs model.

## A step back

So that we can all gain an appreciation for React Server Components, I think it would be helpful to take a step back and speak on a few common rendering strategies when it comes to thinking about React.

### Client-side rendering

When using tools such as **vite** to scaffold a react application, most tutorials speak of a **client rendering** strategy. With this strategy, the user will initially receive an `HTML` document that looks like the following:

```html
<!DOCTYPE html>

<html>
  <body>
    <div id="root"></div>
    <script src="/src/main.js"></script>
  </body>
</html>
```

You'll notice that all the content is missing!! That's because the `main.js` includes all the code we need to mount and run our application -- this includes React, third-party dependencies, all the UI we've written using React and any other piece of code.

Once the JavaScript has been downloaded and parsed, React will come to life, creating all the DOM nodes necessary for our application while attaching any event handlers as well. All these nodes become a child of that singular `div` element within our `HTML` document<ToolTip>The div with the **id** of **root**</ToolTip>. This means that with a **client rendering** strategy, our application will not become visible to the user until all the JavaScript has been downloaded, and parsed, and React has created the DOM nodes. We can see this demonstrated in our example below. Click the button to view a client rendering strategy!

<RSC_Client_Render />

This is a problem because the user will be staring at a blank screen until all of the above processes (HTML, CSS, and JavaScript) have finished. This problem also tends to get worse as the JavaScript bundle gets larger and larger.

There are optimizations to help mitigate the prolonged waiting period; optimizations like lazy loading, loading spinners, etc but these optimizations do not help tackle the main problem at hand. How do we render elements to the screen quickly with a growing bundle size?

### Server-side Rendering

Server-side rendering is a rendering strategy that is aimed at improving this experience. Instead of sending an empty `HTML` file (detailed in the client-side rendering section), the server will generate an HTML document which includes all the elements required for the initial render. We are effectively rendering web pages on the server before sending them to the client. As a result, the user no longer sees a blank screen on the initial render but rather they will see some information about the page. This rendering strategy also helps search engines crawl and index the initial content on the page which is beneficial for Search Engine Optimization.

Consider the following example! Click the **Render Components** button and see what happens!

<RSC_Server_Render />

How does this differ from a client rendering strategy?

We can see that after the HTML is downloaded, we get some content being displayed to us. More specifically, we see that the HTML page being sent from the server contains all the elements needed to render an initial page. Using a server rendering strategy we don't have to wait for the javascript to the downloaded, parsed, and react to spring into action before we see some sort of content.

It's important to note that the HTML file sent to the client on the initial render still includes the **script tag** detailed in the client rendering section as the browser still needs React to run on the client. However, things work a bit differently after the JavaScript bundle has been downloaded. Instead of building all the DOM nodes from scratch, React will use the initial HTML document as a scaffold to **hydrate** the DOM nodes. We use **hydrate** here as a way to refer to the process where React takes over rendering and attaches all event listeners registered on a JSX element.

Therefore, a server-side rendering strategy improves a user's experience by showing some content to the user on initial render without having the user wait for the JavaScript to be downloaded, parsed, and react to spring into action. The user sees some content while all the other stuff is happening in the background and then when all is complete Client-side React will pick up and now we get some interactivity on our page.

<Aside tag="FYI" title="SSR is a generic term">
Server-side rendering is a generic term that encompasses much more than we described above. When we mostly think of server-side rendering, I imagine it looks like the following:

- Request is made for the page
- Server generates an initial HTML document and then sends it to the client
- The user sees some content on the initial render

This is one way to implement server-side rendering and it's typically referred to as server-side rendering at "request" time <ToolTip>You most often see this in frameworks like Remix (now react-router)</ToolTip>. The other type of server-side rendering is done at "build" time; often referred to as static site generation (SSG) <ToolTip>Frameworks like Gatsby specialize in static site generation</ToolTip>. During the bundling of our application at "build" time, we slot in an extra step which allows us to "pre-render" all the HTML for all our different routes.

Essentially we generate static HTML files for all the different routes that are available and then push/store these files on a content delivery network (CDN).

<Expanded>
**SSG** and **SSR** are the two most common types of rendering strategies when it comes to working in React but there are a few rendering strategies to note.

**Incremental Static Regeneration (ISR)** - This is a subset of static site rendering where you can create or update static pages after build time.

</Expanded>

</Aside>

## Data fetching

We've spoken about two major rendering strategies an application can have when it comes to displaying content but for us to fully gain an appreciation for React Server Components, we must also talk about data fetching.

Many of us have been working with React from the client-side rendering perspective using scaffolding tools like **vite**. We previously mentioned that a **client rendering strategy** involves the user receiving a blank `HTML` file which is then populated with content after all the JavaScript has been downloaded, parsed, and React has sprung into action. This means that data-fetching within client-side rendered applications can only begin after React has sprung into action.

We can see can see it visualized here:

<RSC_DataFetchCSR />

This strategy is where you most often see loading spinners to indicate that the content is still waiting to be rendered on screen<ToolTip>Loading spinners will be shown from step 3 until step 7.</ToolTip>. React developers may be familiar with the idea of setting a `isLoading` state variable which is used to conditionally render loading spinners until the content is available.

Although **CSR** is a viable rendering strategy when it comes to data-fetching, there are many situations in which we would want the initial rendered shell to contain some content instead of being blank. As we mentioned above, this goal SSR aims to achieve -- we render an initial shell with some content, download JavaScript and then run react to make our db query and get the rest of the content.

We can see it visualized here:

<RSC_DataFetchSSR />

Looking at these two images above, we can say that **CSR** and **SSR** are very similar as both approaches download JavaScript on the client and then make an additional request to get the remaining content to be rendered on the client. The only difference is where the initial render is taking place -- with CSR this occurs on the client after JS is downloaded on the client whilst with SSR the initial render occurs on the server before the JS is downloaded on the client.

With frameworks like NextJS -- specifically the `/pages` directory -- we could move more of the database querying actions to the server. This was accomplished by exporting one of two functions that would exclusively run on the server from the same file as the component<ToolTip> The function itself was not included in the JavaScript bundle therefore we could access DB's securely within them.</ToolTip>. The two functions were `getServerSideProps` and `getStaticProps`. If you're familiar with the `/pages` directory of NextJS then the following code may be familiar to you.

```jsx
const App = ({ data }) => {
  return <p>The name of the blog is {data.title}</p>;
};

export default App;

export const getServerSideProps = async () => {
  const data = await sql`SELECT * FROM Books`;

  return { props: { title: data } };
};
```

These functions were cool because they returned a `props` object containing the data needed for the component to render with the full content on the initial render. This was an improvement but even with SSR or these modified approaches we were still rendering react components on both the client and the server.

But what if we could exclusively render react components on the server? What would that look like? What could be made possible?

## React Server Components

React server components (**RSC**) are a way to render react components exclusively on the server. These components allow us to write code that seems questionable but magically works!!

Let's move the code snippet from the NextJS `/pages` example into a React Server component to give us a visual representation of what they look like and then we'll talk about it!

```jsx
const App = async () => {
  const data = await sql`SELECT * FROM Books`;

  return <p>The name of the blog is {data.title}</p>;
};

export default App;
```

WAIT WHAT?!???? React Components can be marked as `async`? We can run `db` queries directly inside react components? Isn't that a **HUGE** security risk? How are these things possible?

Server components <ToolTip>I use server components and RSCs interchangeably but they are the same thing </ToolTip> are just the regular semantic react components that we've been writing all along. They are constructed from a function that can define some `props` and then return a piece of `jsx` to render a view. The difference here is that server components are rendered exclusively on the server with the rendered value <ToolTip>Rendered value does not change. More on this later!</ToolTip> being sent to the client to be displayed. As a result, code written inside RSCs is excluded from the JavaScript bundle thereby allowing us to access server-side data sources <ToolTip>This includes but is not limited to databases, filesystems, and micro-services. </ToolTip> directly inside a component.

<Aside tag="FYI" title="The rendered value RSCs produce">
A misnomer about RSCs is that the server exclusively renders a react component and then sends down a finalized HTML string to the client. This idea is partly true in that the server **does** exclusively render a react component but a finalized HTML string **does not** get sent down to the client in the RSC model.

In actuality, the server renders the react component and then sends an **RSC payload** down to the client. This RSC payload is serialized **JSON** that describes to the client how the react component should be built. In other words, the RSC payload is a virtual representation of the component which was rendered on the server.

It looks something like this (simplified version):

<Expanded>

<RSC_Payload />

WOW!!! It's an object! This object is really just a react element that was created from the function call to `react.createElement`. A React element is more like a description that provides the instructions for React to later render a specific component.

So when we talk about server components, we're really talking about running `react.createElement` within a server-only context and then generating this react element. This is passed along to the client in the form of **JSON** and then from there the client knows how to render this react element.

Moreover, we can say that the code needed to generate the react elements for server components **do not** exist within the client bundle so as long as we send this RSC payload alongside the HTML, React can regenerate these server components in the browser.

</Expanded>
</Aside>

Fantastic!! But we've run into a problem though.

RSCs **never re-render** as they run once on the server to generate the UI and then send the result to the client to be displayed. This means that most of the React hooks we've come to love are now incompatible with RSCs. We can't use `useState` because `useState` causes a component to re-render but server components can't be re-rendered.

But I thought the entire point of React was to have interactivity within our components. If we're using RSCs, how do we inject interactivity into our applications?

### Client components

Client components solve this issue!! What?!???? More new terminology???

Client components are nothing new as they are the **"standard react components"** that we've been writing all along. The term is used to distinguish between server components -- the new type of component -- and the **"standard"** react component. This means that client components allow us to access all the react hooks that we're familiar with!! We can use states, effects, browser-only APIs, etc.

However, the term client component is misleading! I wanted to emphasize the point of the **"standard"** react component because we would assume that client components are only rendered on the client. However, that is not the case as client components are rendered both on the client and the server.

<Aside tag="Note" title="Misnomer of RSCs">
A misconception of React server components is that they are a replacement for server-side rendering. It's a fair assumption to make and I'm guilty of this too haha!! They do sound fairly similar but React Server Components are not a replacement for Server Side Rendering. These paradigms can work hand-in-hand or independently of each other.

As we saw above, RSCs are a way to render a component ahead of time in an environment that is separate from a client app while SSR is a rendering strategy that generates an HTML document which includes all the elements required for the initial render.

</Aside>

### Defining client & server components

WOWWW!! We have a **server component** (a new type of component) and a **client component** (a new name for a familiar type of component). So the question remains, how do we go about defining these components when building a react application?

During the initial [conversations of RSCs](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md), the thinking was that we would mark a client component with a `.client.js` extension and a server component with a `.server.js` extension (similar to how it's done in Remix). However, these conventions evolved and we rethought how we specify client & server components.

The new thinking (the one that stuck) is that **all components are assumed to be Server Components by default.** We have to **“opt-in”** for Client Components. We do this by specifying a new directive `use client`.

```jsx
"use client";

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>Current value: {count}</button>
  );
}

export default Counter;
```

We use the `use client` directive to mark a file/component as a client component thus **all the code** in this file will be included within the JavaScript bundle.

When we mark a file with the `use client` directive we are creating a **client boundary** between client and server. Therefore, every component past this boundary will implicitly become a client component.

We can see this demonstrated in the following component tree:

<RSC_React_Component_Tree />

<RSC_TOR_ClientComp />

Looking at the diagram above, it makes sense that we can render client components inside of server components because once the server bundler hits a client boundary, it marks that location and includes the appropriate JavaScript code in the client bundle.

Interesting!! But can we render a server component inside of a client component? We said that once we create a client boundary, we implicitly convert every component within the boundary into a client component. So is it possible?

Technically, no but also yes! We can still render server components inside of client components **if and only if** we pass them as props (ie children props). The important thing to note here is that any component that we **import** into a file marked with `use client` will also **become a client component** as that file/component is now inside the client boundary.

<Aside tag="FYI" title="Why use RSCs?">
So far all the text you’ve been reading thus far, including all the code blocks, are actually **React server components**!

That’s right! These components are not interactive so there’s no need to ship the code to as part of the client bundle. We can do the work on the server and then just send down the rendered value for the client to display. Furthermore, syntax highlighters tend to have very large bundle sizes so to reduce the overall size of the client bundle you receive, it makes sense to render the **code blocks** on the server and then just send down the rendered values to the client.

Components such as the pop quiz you just took, need to be interactive. Therefore, these components are marked as **client components** so it means that the JavaScript needed to render these components is included in the client bundle that you receive.

</Aside>

This interweaving of server components with client components coupled with the ability to define our client boundaries **(opt-in system)** offers many advantages and new ways of structuring our application which we will come to appreciate later on.

## The Story of Server Actions

So far we've been concentrated on defining react server components and how they differ from the newly termed client component. However, we've looked at only one part of the puzzle -- reading data and rendering components in a server-only context. What happens when we mutate data? Do we still have to do this on the client? Is there a way to mutate data exclusively within a server context as well?

This is where **server actions** come into play! Server actions provide a way to run functions/logic exclusively within a server context. This means that mutating data within a database is now as simple as calling a function within your component!

This is awesome because we no longer have to rely on building API routes and hooks to handle a form submission! **We can literally just call a function within our component!**

Let's take a look at what a server action looks like

```js
const serverAction = async () => {
  "use server";
  const data = await sql`INSERT INTO books (name) VALUES ('Book Name')`;
  return data;
};
```

We can appreciate that server actions are just functions at the end of the day but they differ from regular async functions in that they are marked with the `use server` directive at the top of the function <ToolTip>The `use server` directive can also be placed at the top of a separate file to mark all exports of that file as Server Actions</ToolTip>.

We can use server actions as follows:

```jsx
const app = () => {
  return (
    <form action={serverAction}>
      <button type="submit">Submit</button>
    </form>
  );
};
```

Above we see that we have a react component that is rendering out a form element. You'll notice that we are not providing an `onSubmit` handler to handle form submissions but rather we are using an `action` attribute.

Here the `action` attribute is used to invoke the server action which creates a `POST` endpoint behind the scenes and then executes the function within a server context. We can have multiple actions on the same page and React will keep track of what actions correspond to what form submissions <ToolTip>Server actions are tagged in a special way which allows React to keep track </ToolTip>. Server actions can also be executed without the need for a form as we can use the `useTransition` hook to trigger these actions.

<Aside tag="FYI" title="Are server actions only for server components?">
  It's a misnomer that server actions can only be triggered within server
  components. In actuality, we can use server actions within client components
  by just importing them and passing them to the form action attribute, or the
  useTransition hook.
</Aside>

It's important to note that `actions` don't just exist on the server because we can also establish them on the client side but that's a story for another time.

## The little big things

There are a host of questions that arise with the new implementation of React server components and server actions. If we are no longer relying on manually calling an API endpoint, how can we show pending states, rejected states, etc? What benefits arise when we move over to the server action paradigm? Lastly, regarding server components, what does it mean to stream content from the server and what are its benefits?

### Handling pending and rejected states

Several new hooks in react come with the implementation of actions and one of them is the `useFormStatus` hook. **useFormStatus** gives us access to the status information of the last form submission. Using this hook, a component can know if its parent's form (using actions) has been submitted and can respond accordingly. For example, if we want to disable the submit button to prevent multiple submissions from occurring then the **useFormStatus** hook can give the component the necessary information to accomplish that task.

<Aside tag="FYI" title="useFormStatus can only be used in a specific way">
  `useFormStatus` returns the status for a specific `form` element, so for the
  hook to work correctly, it **must be defined inside a component that is a
  child of the `form` element**. It's also a React hook thus it can only be used
  within a client component.
</Aside>

There is also the `useActionState` hook which allows us to update the state of a component based on the results of a form action. In this case, if we `return` from a server action, we can access the return value and use it within the component.

Consider the following server action, useFormStatus, and useFormState example!

```js
export async function getUser(prevState, formData) {
  //... some logic goes here and an error is thrown
  return {
    message: "Please enter a valid email address",
  };
}
```

```jsx
"use client";
import { useActionState } from "react";
import { useFormStatus } from "react-dom";
import { getUser } from "./getUser.js";

const Btn = () => {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      Login
    </button>
  );
};

const Login = () => {
  const [state, formAction] = useActionState({ message: "" }, getUser);
  return (
    <form action={formAction}>
      <label htmlFor="email">Email</label>
      <input type="text" id="email" name="email" required />
      <p> {state?.message} </p>
      <Btn />
    </form>
  );
};
```

Here we can see that the result returned from the server action can be accessed within the component and displayed accordingly. We can also see that we are disabling the login button depending on the status of the form. This syntax drastically improves the developer experience because features that we would have written excess code for can now be accomplished in just a few lines of code!

### Optimistic Updates and UIs

The benefits don't just stop at the developer experience! With this new way of thinking about submitting user inputs, we can begin to build UIs that support optimistic updates. These experiences have been available on mobile platforms for a while now but it's so cool that we can begin to implement on the web platform.

If you're not familiar with optimistic updates/UIs then TL;DR -- optimistic updates allow us to immediately present the user with the intended result after they have taken an action. We optimically show this result even though the action may take some time to complete.

Take a look at the chat component below to see what I mean:

<RSC_Optimistic />

When you send a new message, you immediately see the updated changes with the expected outcome instead of waiting for the server's response. But once the server finishes processing the request, the UI will be rerendered in order to show the correct state. This makes the app feel more responsive and your user is not kept waiting for a long period if they have a slow connection.

In React, we can accomplish optimistic updates using the new `useOptimistic`hook which allows us to show an optimistic state change when an asynchronous action takes place. In the case that an error is thrown, the state will fall back to the previous value before the action took place.

This provides a great experience for the user as they get the sense of rapid behaviours they experience but with the added experience that error will be handled gracefully.

### Streaming

The last point we'll touch on here is the idea of streaming content to our users. When we think of streaming we may think of watching a video on our favourite streaming platform. There we may notice that pieces of content are being downloaded to our devices as we are consuming the content. This is in contrast to the other method of first downloading the entire video before we can watch it. The thinking here is that if we can break up the video into little chunks and then send those chunks to the user as they need, then we can speed up the time to interactive for the given video. This gives the perceived performance improvement for the user and they get to watch the video **"faster"**.

Toggle between the **without streaming** & **with streaming** tabs and click on the **Render Components** button to get a sense of what streaming looks like in action!

<RSC_Streaming />

We can see that in the **without streaming** scenario, we have to wait until the slow component finishes rendering before we see any sort of content. In the **with streaming** scenario, we can get the fast components immediately and then show the slow component once it's available.

Using React, we can accomplish the same experience using a fairly new component. The `suspense` component coupled with react server components allows us to introduce streaming directly within our applications. We can directly render high-priority components and then stream lower-priority components to our users. This way we can reduce our Time to First Byte, and improve our Time to Interactive, thereby allowing users to see and interact with important information more quickly.

## Wrapping up

React Server components bring about a new paradigm of building React applications. It's a whole new way of thinking about and writing react apps!

We've explored the what, the who, the why, and the how of React server components and we've also looked at some of the benefits RSCs enable. We revealed that RSCs are a way to render react components exclusively on the server and it could be done on-demand (coupled with SSR) or be part of the bundler at build time. We showed how the server-only context could enable us to make DB queries alongside other server-only queries directly within our component. We revealed that server components differ heavily from server-side rendering as RSCs send a serialized payload describing how a React component should be built on the client.

Throughout the article, we've constantly reinforced the idea of the server-only context of RSCs. We said that code written inside RSCs is excluded from the JavaScript bundle thereby allowing us to access server-side data sources. We never explicitly said it but this means that RSCs have a lot to do with the bundling process. To get to a stage where we can only run code within a server-only context, the server must decide on what to include in the final JavaScript bundle that is sent to the client. This means that to properly integrate RSCs into an application we must take a top-down approach and start on the server.

<RSC_React_Component_Tree />

The topmost component of an application using RSCs (in the diagram **BlogPage**) will always be a server component. Only then can we decide what children components below are going to be client components. This comes in very handy when we start to think about refactoring our applications to use RSCs.

So where does that leave us?

We talked about some of the implications of moving to a React server component and server action architecture. We said that we gain new abilities such as streaming and optimistic updates which ultimately lead to a better user experience. But in doing so we said that we had to rethink how we approach handling form submissions. The new way of interacting with form submissions brings back the idea of **progressive enhancement** and allows us to optimize our application while still allowing us to create custom experiences.

WOWWWW! **What a journey!!** React server components are truly a new paradigm for building applications! They are **SCARY** because RSCs make us rethink how we should go about building react apps but they also encourage interesting patterns that improve the overall developer and user experience. It's definitely going to be interesting to see what new patterns emerge!!

There's so much more to discover with this new paradigm and it's going to take a lot of getting used to! I'm going to leave you with a few questions to ponder: What happens to the separation of concerns? How does the definition of frontend and backend change? Do react components reclaim this idea of truly being Lego pieces?

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article?? Here's a fun little exercise for you to try out! 👀
<RSC_Exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[Z-Index 99999: A CSS Conundrum]]></title>
            <link>https://www.nonsoo.com/posts/stacking-context</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/stacking-context</guid>
            <pubDate>Sun, 14 Apr 2024 12:25:47 GMT</pubDate>
            <description><![CDATA[The z-index property is a source of constant frustration as it often fails to behave as expected. This may be due to the stacking context; a fundamental concept that underpins the z-index property. It plays a pivotal role in determining how z-indices work, however, despite its significance, the stacking context remains an overlooked concept. In this article, we delve into the intricate relationship between stacking context and z-indices, shedding light on one of the most irritating questions in CSS: why does setting a z-index value as high as 99999 sometimes not work?]]></description>
            <content:encoded><![CDATA[
When building websites or more specifically, assets for websites, we tend to focus on building within the `x` and `y` axis of the web page. We position things from top to bottom and from left to right. This results in the misconception that developers can only place items within a 2D plane when building websites; however, a webpage also consists of a third dimension, the `z` axis<ToolTip>The axis that shows which layers are closer to and further away from you</ToolTip>. CSS gives developers the tools to access and manipulate all three dimensions, therefore, we can explicitly control the stacking order of HTML elements. We accomplish this by adding the `z-index` property to our CSS rules. This property accepts a numerical value which can be a positive<ToolTip>Item will sit on top</ToolTip> or negative number<ToolTip>Item will sit below</ToolTip>.

**Consider the following:**

Looking at the demo below, we can see that we have two boxes which are stacked on top of one another. Following the natural flow of HTML elements, we can see that `.box2` is stacked on top of `.box1` because of the translate property that we've defined.

What happens when we want `.box1` to stack on top of `.box2`? How would we go about solving that problem? Yes of course we could change the order of the HTML elements to solve the problem but are there any other ways?

In the `styles.css` file, let's try defining a `z-index` property on `.box1` -- give it a try!!

<Stacking_context_playground1 />

We can see that by adding the `z-index` property to `.box1` we cause `.box1` to stack on top of `.box2`. Now you may wonder what happens if we add the `z-index` property to `.box2` but give it a higher value than the `z-index` property in `.box1`. Give it a try with the demo above!

**Generally speaking**, elements with a higher z-index value will appear on top. However, this is not always the case and we'll explore why shortly. It's also important to note that if no value for `z-index` is set, the browser will use the document source order to dictate `z-index` instead.

The `z-index` property is one of the CSS rules that are most often misunderstood because when we talk about the `z-index` we sometimes forget to talk about the important concepts that make the `z-index` property possible. This results in a lot of frustration when trying to properly layer elements in web applications because sometimes the `z-index` property does not behave as expected. In this article, we'll explore things like layers & groups, the stacking context, and how it all applies to the `z-index` property.

## Layers and Groups

Earlier we mentioned that the `z-index` property introduces the idea of having layers within our web page. We identified that it gives us access to the third dimension -- z-axis -- thus allowing us to control how close or far an object is away from us.

If you've used graphics software such as Adobe Illustrator or Affinity Design, then the concept of layering assets to create a final image may be familiar to you. For those types of software, layers are an important tool that allow users to add components to an image and work on them independently without permanently changing the original image.

Users who are using layers in these types of software most often add one layer to adjust the colour & brightness of the image (layer 1) and then add another layer to add some special effects (layer 2). This gives users the ability to separate concerns so that the special effects that are added in layer 2 do not affect the change in colour or brightness found in layer 1. Talking about layers in this context automatically implies that a stacking order exists. We can see this demonstrated in the image below -- here we have the bottom-most layer, the middle, and then the top layer of the image.

<Stacking_context_layer1 />

The stacking order of the image can always be rearranged thus there could be a scenario where layer 2 is below layer 1 which is below layer 3. If that were the case, then it would look something like the image below.

<Stacking_context_layer2 />

These programs also give you the ability to group layers to prevent cluttering and give you a sense of organization in your layers. This means that if we create multiple groups then we now create a stacking order for our groups.

Let's say we had the following scenario:

<Stacking_context_layer3 />

Looking at the above example we can re-order Group 1 and Group 2 so that Group 2 is now on top of Group 1. Doing this implies that all of the layers within Group 2 are now on top of the layers within Group 1. Now let's see what happens when we change the layer order within the groups. Drag the layers within each group and see how it affects the topmost layer output.

The important thing to notice here is that changing the layer order within the groups **does not** change the layer order of the groups. No matter how many times we change the order of D, E, and F, Group 2 will always be the **topmost** layer if it's on top of Group 1. In other words, any layers within group 2 will always show up on top of all the layers in group 1. Therefore, if we wanted **layer B** to be the topmost layer, then we would have to move **Group 1** to the top of the horizontal stack and **layer B** to the top of the verticle stack. Give it a try in the example above!

When it comes to fully understanding the `z-index` and the mysteries behind it, these concepts of layers and groups are the secrets that help us solve the conundrum.

## Understanding the stacking context

So you've been working really hard to create this layered system but it seems like nothing is working!! Even the cheeky hack of setting the `z-index` to a really high value such as **999999** doesn't seem to work. If you're unsure of what I'm referring to, here's a coding playground to check out.

<Stacking_context_playground2 />

Here we have two boxes, `.box1` and `.box2`, which are overlapping. Right now `.box2` overlapping `.box1` but in order to change that we have to set the `z-index` property value on `.box1` to be higher than `.box2` right?!?!? Let's try it -- did it work?

It's really weird because earlier we mentioned that elements that have a higher `z-index` value would appear on top but in the above example, it doesn't seem to be the case. Seriously, what's going on here?!?!?

To understand this better, we first have to talk about the **stacking context**.

A **stacking context** is a group of elements that have a common parent and together this group moves up and down the z-axis. To put it another way, a stacking context is a space for layering to occur within a three-dimensional space. They are very similar to the groups/folders we were talking about earlier. This means that elements can exist within a stacking context and establish a stacking order -- ie an order to the layers. Within an individual stacking context, we can now begin to re-arrange the order of the elements and we do this using the `z-index` property. Looking at the folder example from earlier, just as we could have multiple groups that are siblings of each other, we can have multiple stacking contexts that are siblings of each other.

An important thing to note is that the stacking context cannot be escaped by its children once it has been established on the parent. Just as the re-ordering of layers within an individual group did not change the order of the groups themselves, the re-ordering of layers within an individual stacking context does not change the order of the stacking context itself.

This is really crucial and it explains why adding a `z-index` value of "99999999" sometimes doesn't work -- this is especially the case in our example above.

Knowing this, can you fix this example... Give it a try!!

<Stacking_context_playground2 />

Adding a `z-index` value of "99999999" doesn't work in this case because `.box1` is trapped within a stacking context that is below `.box2`. Let's see what happens when we add a `z-index` property on the parent of `.box1` <ToolTip> Note the value here has to be higher than the `z-index` value on box 2</ToolTip>.

Hooray it works!!!

## Creating new stacking contexts

I hope we've solved a lot of frustrations with the `z-index` property by understanding how stacking context works. But a few questions still remain and one in particular is: **How are new stacking contexts even created?**

In short, a new stacking context is created whenever a `position` property is set to a value other than `static` and a `z-index` property is defined. I say this with a grain of salt because it is more nuanced than what we've described.

<Aside title="What's the deal with position?" tag="FYI">
The `position` property is one of those oddball CSS properties that is used to well position elements on a web page. It has 5 known values: `fixed`, `relative`, `absolute`, `sticky`, and `static`.
<Expanded>
By default, all elements are statically positioned on the page meaning that they follow their natural order defined by flow root. `Block` level elements stack from top to bottom and `inline` elements remain inline.

Position `absolute` is a weird one because elements that are absolutely positioned are positioned relative to their nearest ancestor that has a position of `relative`. If none exist then the absolutely positioned elements will be positioned relative to the initial containing block. The other weird thing is that these elements are removed from the normal document flow thus they behave as if they don't exist on the page -- ie other elements are not aware of their existence.

Position `relative` elements are positioned according to the normal flow of the document, and then can be controlled based on the values of `top`, `right`, `bottom`, and `left`. Other elements on the page are aware of elements that are relatively positioned.

Position `fixed` elements are positioned relative to the initial containing block which is most often the viewport. These elements are also removed from the normal document flow.

</Expanded>
</Aside>

A new stacking context is defined on an element that has a `position` property set to either absolute or relative **and** has a `z-index` property defined as well. We've seen this in the examples above, however, this is not the only way! Here are some others:

- Setting `opacity` to a value less than `1`
- Setting `position` to `fixed` or `sticky` (No z-index needed for these values!)
- Adding a `z-index` to a child inside a `display: flex` or `display: grid` container
- Using `transform`, `filter`, `clip-path`, or `perspective`
- Using `will-change` with a value like `opacity` or `transform` (useful for animations)
- Setting the value of `container-type` to `size` or `inline-size` (useful for container queries)
- Explicitly creating a context with `isolation: isolate`

There are a few other ways to create new stacking contexts and you can find [the full list on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context).

### Something to highlight

As we've seen above, there are many ways to create a new stacking context but a common misconception still exists.

**POP QUIZ!!**
<Stacking_context_trueFalse_flexBox />

Let's check out the example below:

<Stacking_context_playground3 />

In the example above we can see that we're using the `z-index` property on an element that does not define a `position` property. We can do this because this element's parent is a flex container. When we create a new flex-container, we are also creating a new stacking context thus flex-children have the ability to use the `z-index` property even though their position property is set to static.

To sum up, a stacking context can be created in one of two ways:

1. By creating a new region using the position property
2. By creating a new composite layer

## Wrapping up

The frustration with the `z-index` property is one that I have personally battled with for a while so I empathize with anyone who has some battle scars!! The `z-index` property is a really powerful tool that allows us to position elements within a three-dimensional space on the web. It does this as it allows us to explicitly control the stacking order of HTML elements, thereby enabling us to position elements close or further away from the viewer.

To fully understand the `z-index` property, we first had to look at defining different layers and how that correlated with layers that were defined within groups. We found that changing the layer order within the groups **did not** change the layer order of the groups. This meant that if we created multiple groups then we now created a stacking order for those groups.

We explored the stacking context and how it relates to layers, groups, and the `z-index` property. We found that we could have multiple stacking contexts and that the re-ordering of layers within an individual stacking context did not change the order of the stacking context itself. We finally solved why adding a `z-index` value of **"99999999"** sometimes doesn't work!! YES!

To finish off, it's important to recognize that `z-index` only works within a stacking context because its job is to re-order layers within a group or better yet, within a stacking context. Therefore, if no stacking context exists, then the `z-index` property will not work.

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article?? Here's a fun little exercise for you to try out! 👀

<Stacking_context_exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>css</category>
        </item>
        <item>
            <title><![CDATA[Thinking about a new responsive web]]></title>
            <link>https://www.nonsoo.com/posts/container-queries</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/container-queries</guid>
            <pubDate>Sun, 14 Apr 2024 12:25:37 GMT</pubDate>
            <description><![CDATA[Design on the web has changed drastically over the years. Tools such as media queries, flexbox, and CSS grid allow developers to reshape layouts on the web to suit the devices of many users. Although we are still iterating and uncovering answers to questions that drive the user experience on websites, the shift to component-based development has made it increasingly important to think about how components define their own layout. This article explores container queries and how they iterate on the idea of micro-layouts.]]></description>
            <content:encoded><![CDATA[
Design on the web has changed drastically over the years; So much so that we now have the tools to build on ideas that we once thought were impossible. It's an exciting time to be a front-end developer, and I don't say this lightly! There was a time when structuring layouts on the web was very tedious, and implementing responsive layouts was not even a question in mind. Developers were forced to build multiples website to ensure that desktop and mobile users had a great user experience when visiting a website.

It's important to remember that user experience drives the design of user interfaces, and layout is a critical component of those interfaces. Therefore, as the complexity of those interfaces grows, so do the options for designing layouts for them.

Let's think about the following questions as they relate to responsive layouts:

- How does the layout of a page respond when the size of our viewport -- our canvas in which our website is built -- changes? At smaller screen sizes, are we putting more important information at the top or are we showing a zoomed-out version of the page?
- What happens to the size of elements on the page with a change in viewport size?

There was a time when questions like the ones above were difficult to answer, but the introduction of the responsive web, allowed us to begin uncovering the answers to those questions.

## A look at where we are

Tools such as media queries, flexbox, and CSS grid allowed developers to reshape layouts on the web to suit the devices of many users. Media queries brought us the ability to query the size of the viewport, thereby allowing us to modify the CSS properties on DOM elements with a change in viewport size. This addition meant that we could now show/hide and even re-order DOM elements based on the viewport size.

Let's imagine that this box is our viewport. As we make the size of this viewport smaller (dragging the slider), we begin to see a layout shift -- Elements that were once in rows are now put into columns, and elements that were once present are now hidden.

<ContainerQuery_ViewportEx />

This can be observed on any modern website, including this one! Try changing the size of your web browser!

Flexbox brought about the idea of flexible containers and items, and it allowed us to explore what happens to the intrinsic size of an item as the available space changes. Our options grew as we could now begin to wonder how elements could distribute the available space to properly fit within the viewport. Thereby allowing us to ask deeper questions about what it means to have a more flexible/fluid layout. This is of course in addition to our ability to hide elements or move to a column layout at smaller screen sizes with media queries. Josh Comeau has an incredible [article](https://www.joshwcomeau.com/css/interactive-guide-to-flexbox/) that explores Flexbox and its awesome quirks -- it's worth the read!

CSS grid, commonly known as Grid, brought about the idea of a two-dimensional grid system that redefined our approach to developing user interfaces. It allowed us to think of our page as a grid system, thereby making the elements on our page items on that grid. This allowed us to forgo workarounds for implementing certain layouts, as now we could place items anywhere within our predefined grid system. As with Flexbox, CSS grid is another tool in our arsenal that we can use in conjunction with media queries and Flexbox to create responsive layouts.

Although we are still iterating and uncovering answers to questions that drive the user experience on websites, the shift to component-based development has made it increasingly important to think about how components define their own layout. This can be defined as **macro** & **micro** layout; **macro layout** being the layout that defines the overall page structure/layout and **micro layout** being the layout that defines the intrinsic layout of a component. The tools described above have allowed us to iterate on macro layouts but as development has shifted towards more component-based layouts, we have to iterate on development with micro layouts.

## Container queries

Container queries iterate on the idea of micro layouts, as they allow us to set a defined container and have the children query the size of the container. Similar to media queries, container queries allow us to modify the CSS properties on DOM elements, thereby allowing us to show/hide, re-order DOM elements, and modify other properties based on the size of a container. An important distinction to be aware of is that **media queries** allow us to query the size of the viewport, whereas **container queries** allow us to query the size of a defined container.

Container queries move us beyond considering only the viewport, and allow any component or element to respond to a defined container’s width -- Stephanie Eckles.

This solves a unique problem in that container queries allow us to develop components that are intrinsically responsive. This allows us to have confidence that we can build a component once, but use it anywhere. More specifically, a component that is used in the main section of a web page can now be put in a sidebar without adding any additional utility classes that target the component in the sidebar.

Let's check out the example below in which we've defined some components that make use of container queries.

<ContainerQuery_QueryEx />

We can see that the same component is being rendered differently depending on the available space. When there is not enough space, the black box and text stack. But when the space becomes wide enough, the black box and text can now be side-by-side and the title can have a bold font weight.

## Getting started with container queries

Container queries were recently introduced into the CSS spec, and as of the time of writing, they are available for use across the major browsers. The first step to getting container queries to work is by setting containment on a parent element. Containment allows developers to tell the browser what parts of the page are encapsulated as a set, thereby providing isolation of a DOM subtree from the rest of the page. Moreover, it's hinting to the browser which parts of the page can be treated as independent, therefore, setting containment on an element enables browsers to isolate queries for that container. Four types of containment can be set on an element, and they include:

1. size
2. layout
3. style
4. paint

If you've been following the formation of the container query spec then you may recognize that the `contain` property was used to define a container. Using the `contain` property, you would have to set `style` `layout` and `size` containment at the same time to properly define the container. However, there have been revisions in the container query spec and it's now a lot simpler to set containment on an element. `container-type` allows us to specify the `size` containment on an element, while the `style` and `layout` containment are automatically added.

Let's say that we had the following HTML snippet, and we wanted a section that appears both in our main section and inside a sidebar:

```html
<main>
  <section>...</section>
  <section class="container">...</section>
  <section>...</section>
</main>
<aside>
  <section class="container">...</section>
</aside>
```

In our CSS we would select our section that has the class of container and set our `container-type` property on this selector. Since `container-type` is a shorthand for setting the size containment, it has one of three values:

1. inline-size - Establishes queries on the **inline axis** of a container.
2. size - Establishes queries on both the **block** and **inline** axis of a container.
3. normal - **Does not** establish a query container for any container size queries but remains a query container for style queries.

Since we only want to query for the width of the container, we're going to set the `container-type` to inline-size.

<Aside title="Things to be careful about" tag="FYI">
	By setting `container-type` to inline-size we are telling the browser that the **container itself** and **not its children** is responsible for setting its size in the inline direction. This means that we have to explicitly specify the size of the container in the inline direction. For the English language, this would be the width of the container.

    However, when we change the `container-type` to size, we are telling the browser that the **container itself** and **not its children** is responsible for setting its size in both the inline and block direction. This means that we have to explicitly specify the size of the container in both the **inline** and **block** directions. For the English language, this would be the width and height of the container.

    Most often we will be using the inline-size when setting the `container-type` on an element.

</Aside>

Although optional, we can also name our container with the `container-name` property. This may come in handy if we were dealing with multiple containers or even nested containers. A nice shorthand for both the `container-type` and `container-name` is the `container` property. Using this property, we can specify the `container-type` and `container-name` in a single line. It's as follows:

```css
.container {
  container: container-name / container-type;
}
```

Now that we've defined our container, we can begin writing our queries to set styles for the children. A queried element will use its nearest ancestor that has containment applied. This is important to keep in mind because nesting containers is possible and, as you may recall, we were speaking earlier about how the `container-name` property may come in handy when nesting containers. Further, if we are trying to query a container when there are no containers defined, then the query itself would be disregarded. It will fall back to the version of the styles applied to elements before the query.

So, how do we write a container query? As I alluded to above, container queries are similar to media queries, and these similarities extend to their syntax. Container queries begin with `@container` and are then followed by the optional container name and then the query parameter. It looks something like this

```css
@containter optional-name-parameter (min-width:300px) {
  ... things go in here;
}
```

It's important to note that we are querying against the computed `min-width` rather than the defined style of `min-width` -- this may be useful when setting a `container-type` on an element that is a flex item or a grid item. Furthermore, the rules applied inside a container query only affect the descendants of the container and not the container itself -- ie/ containers cannot query themselves. Going back to the HTML markup above, we cannot apply rules to the section that has the class of container if that element is a container, and is being used to set a query. However, we can apply rules to the descendants of elements inside the container.

Let's take a look at what writing a container query would look like for a card component:

{/* A card demo that shows two cards with different styles being applied depending on the width of their container -- Use sand pack */}

<ContainerQuery_Playground />

Looking at the CSS file, we can see that we've set containment on the element that has a class of **card**. We're now going to be querying the container to apply some styles when the container is larger than a certain size -- in this case when the width is greater than 300px. Here we are changing the flex orientation to a row and using a larger font size. This is so awesome because this is now an intrinsic layout as we're specifying styles based on the size of the container rather than the size of the page.

<Aside title="Structuring our queries" tag="FYI">
  The container/media query similarities also extend to the way we approach
  structuring the queries. There are many different thoughts and approaches to
  properly structuring queries but I find adopting a "mobile-first" approach is
  the most intuitive. I say "mobile-first" as we can start with the smallest
  layout as the default and then progressively query on larger container sizes.
</Aside>

Earlier we mentioned that a container cannot query itself, however, a container can be used as part of the CSS selector for its children. Meaning that you can use a container as a compound selector or a way to select its descendants.

## Container queries in a flex or grid layout

When working with flex or grid layouts, it may be tempting to think of flex/grid containers as the container in which you want to query to change styles within the flex/grid item. Although doing this may be useful in some situations, in most situations it often yields unexpected results. Most often, the flex/grid container is part of the overall page layout, which then responds to the size of the viewport. Therefore, putting a `container-type` property on a flex/grid container that is part of the overall page layout makes the container query act more like a media query. This is the case as the computed width of those flex/grid containers only changes as the size of the viewport changes.

We're now in this catch-22 as:

1. We can't put the `container-type` property on elements that we want to style as a result of our query -- IE/ containers can't query themselves
2. We may end up creating a container query that acts more like a media query

How do we solve this? 🤨

We're going to put the `container-type` property on a flex/grid item, however, the flex/grid item may not be the element that you think.

```html
<main>
  <section class="container"><p>...</p></section>
  <section class="container"><p>...</p></section>
  <section class="container"><p>...</p></section>
</main>
```

We're going to wrap our elements in a wrapper class which then becomes the flex/grid item to which the `container-type` property is added. To be specific, `main` would be a flex/grid container while `section` elements with the class of container would have the `container-type` property added in CSS.

We spoke a bit earlier about using the `container-type` property with elements that were either a flex item or a grid item. Moreover, we established that the container query parameter uses the computed width rather than the defined style width. This rule is especially important for `flex-items` as the width or flex-basis that is set for that item is more of an idealized value -- Josh Comeau speaks about this more in this [article](https://www.joshwcomeau.com/css/interactive-guide-to-flexbox/). Therefore, when querying for a width of 300px, the query parameter is going to be looking at the computed width of the flex-item rather than the width or flex-basis that is set on that item. This is also important for `grid-items` in which the column size is set using the `fr` unit.

Pop Quiz!
<ContainerQuery_Quiz />

I think it's important to be aware of the relationship between containment and flexible items, especially as we've moved from rigid layouts to more fluid and flexible layouts. It's weird to think about, as container queries have removed intrinsic sizing on elements that have a container defined. But if those elements are also flexible, then they retain the ability to grow and shrink, thus the container itself is now flexible. I think this establishes a new dimension that adds to the fluidity of micro-layouts, as components that define their own layout can now respond to their environment.

Consider the following - Drag the slider to change the width of the container and observe what happens to the layout of the cards. Just so you're aware, each of these cards is a flex-item.

<ContainerQuery_FluidLayout />

## The little big things

Container queries have some side effects that would be useful to know. We spoke a bit earlier about how setting containment on an element allows developers to tell the browser what parts of the page are encapsulated as a set, thereby providing isolation of a DOM subtree from the rest of the page. Since setting containment also includes setting layout containment, we are telling the browser that everything needed to construct the layout of this element and its descendants is scoped within the element itself. Meaning that the browser does not have to look outside that element to know how to construct the layout for that element and its descendants.

Having the layout scoped to the element means that we establish a new **formatting context** thus no more collapsing margins. This is similar to layout algorithms like flex and grid in that these algorithms do not have any collapsing margins aswell. Further, the element that gets containment will also be the **containing block** for fixed and absolutely positioned elements -- this is similar to putting `position:relative` on a parent element. You also create a new **stacking context**, so you now have the ability to use the `z-index` property.

Container queries also introduce a range of new units that add to the fluidity and flexibility of a container. These units are similar to viewport units in that they are relative units but instead of being based on the size of the viewport, they are based on the size of the container. These units include:

- **cqw** for the container query width unit
- **cqh** for the container query height unit
- **cqi** for the container query inline-size unit which specifies the size in the inline direction
- **cqb** for the container query block unit which specifies the size in the block direction.
- **cqmin** is a container query unit that picks the smaller value of either `cqi` or `cqb`
- **cqmax** is a container query unit that picks the larger value of either `cqi` or `cqb`

<Aside title="Caution" tag="Note">
	For the container query units, if there is no container defined then units will be looking at the viewport for a definition. **This means that 1cqw will equal to 1vw.**

    Further, if your `container-type` is set to **inline-size** then **cqb** will act like a viewport height since it is unaware of the height of its container. This changes if `container-type` is set to **size**. Moreover, **cqmin** and **cqmax** start working properly if the `container-type` is set to **size**.

</Aside>

I want to bring your attention back to the demo above -- the demo with the user cards and slider. If you look closely, you'll notice that the font size of the name changes as you change the size of the container. This is really cool because now we can create variable fonts sizes that are scoped to the size of the container. Variable font sizes have been a thing for a while because of the introduction of viewport units, however, we can now make these font sizes respond to the size of the container rather than the viewport. This is made possible by the container query units.

The impressive thing is that this variability is not limited to just the font size. We can also create variable padding and margin sizes. We may want small amounts of padding when the container has limited space, but as we increase the available space inside the container, we may also want to increase the padding as well.

## Wrapping up

Design on the web has changed drastically over the years as we've moved from intuiting hacks that solve obscure problems about layout on the web to an era of responsive design. These problems and hacks have allowed us to think about what it means to have a webpage that responds to the type of device it's presented on -- bringing about layouts that move away from rigidity, and towards fluidity. We're now in a new era of design on the web!

Jen Simmons said it best when she said, **"we're now in the era of intrinsic design"**. Container queries are something special as they allow us to think about what it means to have a responsive component. Moreover, they've allowed us to overcome the last hurdle of what it means to have a component design system, as components can now own and define their own layout. **We can now truly create a component once, but use it everywhere!**

Container queries however do not stop at querying for just the size of the container. Just as media queries now allow us to query for user preferences, in the future we may be able to query for more than just a containers size. There is experimentation being done on what it means to query the style or state of a container. If a container has a certain style or is in a certain state (is the container currently stuck or not?), what styles can we apply to its children? Geoff Graham explores container style queries in the following [article](https://css-tricks.com/digging-deeper-into-container-style-queries/) and Ahmad Shadeed's new [article](https://ishadeed.com/article/css-container-style-queries/) diagrams different use cases for style queries.

It's an exciting time to be a frontend developer, as the future of design on the web looks bright and exciting!!

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>css</category>
        </item>
        <item>
            <title><![CDATA[Z-Index 99999: A CSS Conundrum]]></title>
            <link>https://www.nonsoo.com/posts/stacking-context</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/stacking-context</guid>
            <pubDate>Mon, 23 Oct 2023 19:22:43 GMT</pubDate>
            <description><![CDATA[The z-index property is a source of constant frustration as it often fails to behave as expected. This may be due to the stacking context; a fundamental concept that underpins the z-index property. It plays a pivotal role in determining how z-indices work, however, despite its significance, the stacking context remains an overlooked concept. In this article, we delve into the intricate relationship between stacking context and z-indices, shedding light on one of the most irritating questions in CSS: why does setting a z-index value as high as 99999 sometimes not work?]]></description>
            <content:encoded><![CDATA[
When building websites or more specifically, assets for websites, we tend to focus on building within the `x` and `y` axis of the web page. We position things from top to bottom and from left to right. This results in the misconception that developers can only place items within a 2D plane when building websites; however, a webpage also consists of a third dimension, the `z` axis<ToolTip>The axis that shows which layers are closer to and further away from you</ToolTip>. CSS gives developers the tools to access and manipulate all three dimensions, therefore, we can explicitly control the stacking order of HTML elements. We accomplish this by adding the `z-index` property to our CSS rules. This property accepts a numerical value which can be a positive<ToolTip>Item will sit on top</ToolTip> or negative number<ToolTip>Item will sit below</ToolTip>.

**Consider the following:**

Looking at the demo below, we can see that we have two boxes which are stacked on top of one another. Following the natural flow of HTML elements, we can see that `.box2` is stacked on top of `.box1` because of the translate property that we've defined.

What happens when we want `.box1` to stack on top of `.box2`? How would we go about solving that problem? Yes of course we could change the order of the HTML elements to solve the problem but are there any other ways?

In the `styles.css` file, let's try defining a `z-index` property on `.box1` -- give it a try!!

<Stacking_context_playground1 />

We can see that by adding the `z-index` property to `.box1` we cause `.box1` to stack on top of `.box2`. Now you may wonder what happens if we add the `z-index` property to `.box2` but give it a higher value than the `z-index` property in `.box1`. Give it a try with the demo above!

**Generally speaking**, elements with a higher z-index value will appear on top. However, this is not always the case and we'll explore why shortly. It's also important to note that if no value for `z-index` is set, the browser will use the document source order to dictate `z-index` instead.

The `z-index` property is one of the CSS rules that are most often misunderstood because when we talk about the `z-index` we sometimes forget to talk about the important concepts that make the `z-index` property possible. This results in a lot of frustration when trying to properly layer elements in web applications because sometimes the `z-index` property does not behave as expected. In this article, we'll explore things like layers & groups, the stacking context, and how it all applies to the `z-index` property.

## Layers and Groups

Earlier we mentioned that the `z-index` property introduces the idea of having layers within our web page. We identified that it gives us access to the third dimension -- z-axis -- thus allowing us to control how close or far an object is away from us.

If you've used graphics software such as Adobe Illustrator or Affinity Design, then the concept of layering assets to create a final image may be familiar to you. For those types of software, layers are an important tool that allow users to add components to an image and work on them independently without permanently changing the original image.

Users who are using layers in these types of software most often add one layer to adjust the colour & brightness of the image (layer 1) and then add another layer to add some special effects (layer 2). This gives users the ability to separate concerns so that the special effects that are added in layer 2 do not affect the change in colour or brightness found in layer 1. Talking about layers in this context automatically implies that a stacking order exists. We can see this demonstrated in the image below -- here we have the bottom-most layer, the middle, and then the top layer of the image.

<Stacking_context_layer1 />

The stacking order of the image can always be rearranged thus there could be a scenario where layer 2 is below layer 1 which is below layer 3. If that were the case, then it would look something like the image below.

<Stacking_context_layer2 />

These programs also give you the ability to group layers to prevent cluttering and give you a sense of organization in your layers. This means that if we create multiple groups then we now create a stacking order for our groups.

Let's say we had the following scenario:

<Stacking_context_layer3 />

Looking at the above example we can re-order Group 1 and Group 2 so that Group 2 is now on top of Group 1. Doing this implies that all of the layers within Group 2 are now on top of the layers within Group 1. Now let's see what happens when we change the layer order within the groups. Drag the layers within each group and see how it affects the topmost layer output.

The important thing to notice here is that changing the layer order within the groups **does not** change the layer order of the groups. No matter how many times we change the order of D, E, and F, Group 2 will always be the **topmost** layer if it's on top of Group 1. In other words, any layers within group 2 will always show up on top of all the layers in group 1. Therefore, if we wanted **layer B** to be the topmost layer, then we would have to move **Group 1** to the top of the horizontal stack and **layer B** to the top of the verticle stack. Give it a try in the example above!

When it comes to fully understanding the `z-index` and the mysteries behind it, these concepts of layers and groups are the secrets that help us solve the conundrum.

## Understanding the stacking context

So you've been working really hard to create this layered system but it seems like nothing is working!! Even the cheeky hack of setting the `z-index` to a really high value such as **999999** doesn't seem to work. If you're unsure of what I'm referring to, here's a coding playground to check out.

<Stacking_context_playground2 />

Here we have two boxes, `.box1` and `.box2`, which are overlapping. Right now `.box2` overlapping `.box1` but in order to change that we have to set the `z-index` property value on `.box1` to be higher than `.box2` right?!?!? Let's try it -- did it work?

It's really weird because earlier we mentioned that elements that have a higher `z-index` value would appear on top but in the above example, it doesn't seem to be the case. Seriously, what's going on here?!?!?

To understand this better, we first have to talk about the **stacking context**.

A **stacking context** is a group of elements that have a common parent and together this group moves up and down the z-axis. To put it another way, a stacking context is a space for layering to occur within a three-dimensional space. They are very similar to the groups/folders we were talking about earlier. This means that elements can exist within a stacking context and establish a stacking order -- ie an order to the layers. Within an individual stacking context, we can now begin to re-arrange the order of the elements and we do this using the `z-index` property. Looking at the folder example from earlier, just as we could have multiple groups that are siblings of each other, we can have multiple stacking contexts that are siblings of each other.

An important thing to note is that the stacking context cannot be escaped by its children once it has been established on the parent. Just as the re-ordering of layers within an individual group did not change the order of the groups themselves, the re-ordering of layers within an individual stacking context does not change the order of the stacking context itself.

This is really crucial and it explains why adding a `z-index` value of "99999999" sometimes doesn't work -- this is especially the case in our example above.

Knowing this, can you fix this example... Give it a try!!

<Stacking_context_playground2 />

Adding a `z-index` value of "99999999" doesn't work in this case because `.box1` is trapped within a stacking context that is below `.box2`. Let's see what happens when we add a `z-index` property on the parent of `.box1` <ToolTip> Note the value here has to be higher than the `z-index` value on box 2</ToolTip>.

Hooray it works!!!

## Creating new stacking contexts

I hope we've solved a lot of frustrations with the `z-index` property by understanding how stacking context works. But a few questions still remain and one in particular is: **How are new stacking contexts even created?**

In short, a new stacking context is created whenever a `position` property is set to a value other than `static` and a `z-index` property is defined. I say this with a grain of salt because it is more nuanced than what we've described.

<Aside title="What's the deal with position?" tag="FYI">
The `position` property is one of those oddball CSS properties that is used to well position elements on a web page. It has 5 known values: `fixed`, `relative`, `absolute`, `sticky`, and `static`.
<Expanded>
By default, all elements are statically positioned on the page meaning that they follow their natural order defined by flow root. `Block` level elements stack from top to bottom and `inline` elements remain inline.

Position `absolute` is a weird one because elements that are absolutely positioned are positioned relative to their nearest ancestor that has a position of `relative`. If none exist then the absolutely positioned elements will be positioned relative to the initial containing block. The other weird thing is that these elements are removed from the normal document flow thus they behave as if they don't exist on the page -- ie other elements are not aware of their existence.

Position `relative` elements are positioned according to the normal flow of the document, and then can be controlled based on the values of `top`, `right`, `bottom`, and `left`. Other elements on the page are aware of elements that are relatively positioned.

Position `fixed` elements are positioned relative to the initial containing block which is most often the viewport. These elements are also removed from the normal document flow.

</Expanded>
</Aside>

A new stacking context is defined on an element that has a `position` property set to either absolute or relative **and** has a `z-index` property defined as well. We've seen this in the examples above, however, this is not the only way! Here are some others:

- Setting `opacity` to a value less than `1`
- Setting `position` to `fixed` or `sticky` (No z-index needed for these values!)
- Adding a `z-index` to a child inside a `display: flex` or `display: grid` container
- Using `transform`, `filter`, `clip-path`, or `perspective`
- Using `will-change` with a value like `opacity` or `transform` (useful for animations)
- Setting the value of `container-type` to `size` or `inline-size` (useful for container queries)
- Explicitly creating a context with `isolation: isolate`

There are a few other ways to create new stacking contexts and you can find [the full list on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context).

### Something to highlight

As we've seen above, there are many ways to create a new stacking context but a common misconception still exists.

**POP QUIZ!!**
<Stacking_context_trueFalse_flexBox />

Let's check out the example below:

<Stacking_context_playground3 />

In the example above we can see that we're using the `z-index` property on an element that does not define a `position` property. We can do this because this element's parent is a flex container. When we create a new flex-container, we are also creating a new stacking context thus flex-children have the ability to use the `z-index` property even though their position property is set to static.

To sum up, a stacking context can be created in one of two ways:

1. By creating a new region using the position property
2. By creating a new composite layer

## Wrapping up

The frustration with the `z-index` property is one that I have personally battled with for a while so I empathize with anyone who has some battle scars!! The `z-index` property is a really powerful tool that allows us to position elements within a three-dimensional space on the web. It does this as it allows us to explicitly control the stacking order of HTML elements, thereby enabling us to position elements close or further away from the viewer.

To fully understand the `z-index` property, we first had to look at defining different layers and how that correlated with layers that were defined within groups. We found that changing the layer order within the groups **did not** change the layer order of the groups. This meant that if we created multiple groups then we now created a stacking order for those groups.

We explored the stacking context and how it relates to layers, groups, and the `z-index` property. We found that we could have multiple stacking contexts and that the re-ordering of layers within an individual stacking context did not change the order of the stacking context itself. We finally solved why adding a `z-index` value of **"99999999"** sometimes doesn't work!! YES!

To finish off, it's important to recognize that `z-index` only works within a stacking context because its job is to re-order layers within a group or better yet, within a stacking context. Therefore, if no stacking context exists, then the `z-index` property will not work.

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article?? Here's a fun little exercise for you to try out! 👀

<Stacking_context_exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>css</category>
        </item>
        <item>
            <title><![CDATA[What's at the edge?]]></title>
            <link>https://www.nonsoo.com/posts/the-edge</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/the-edge</guid>
            <pubDate>Thu, 12 Oct 2023 14:44:46 GMT</pubDate>
            <description><![CDATA[As technology races forward, the need for tools and infrastructure that facilitate rapid and efficient data delivery becomes increasingly pressing. This article explores technologies like serverless and edge computing as solutions that allow us to meet the demand for faster and more efficient data delivery. We examine the intricacies of edge computing and we uncover its advantages and disadvantages, while also exploring its potential impact.]]></description>
            <content:encoded><![CDATA[
How fast can we deliver data to the users of our application? Why is there such importance in moving data processing closer to our end users? What are the implications of moving data closer to our end users? These are some questions that come to mind as developers are building on products and applications that have the potential to impact a larger scale audience. Technology is advancing at a rapid pace, and thus the demand for faster and more efficient data processing is on the rise. To meet such a demand, we as developers must build the tools and infrastructure that allow for fast and efficient data delivery.

The **"Edge"** is a solution that has the potential to address many of these concerns as it allows for the processing of data closer to our end-user. It divorces the idea that processing data must occur on a single centralized cloud infrastructure and instills the idea that data processing can occur at the edge of many networks. The edge is an umbrella term that encompasses many different technologies like storage, compute, and most recently data. Thus it's not surprising for someone to refer to the edge as edge compute, edge storage, or edge data.

Edge computing has a lot of benefits and it opens up an expansive array of new questions as it also has involvement with **IOT** (Internet of Things) devices -- this brings hardware and software closer together. Although edge computing is an exciting area of conversation, there are, however, some potential areas where it falls short. Nonetheless, the **Edge** is something we should be excited about and start adopting within the application we build today. Throughout this article, we will explore the inner workings of edge computing, its advantages and disadvantages, and the potential areas in which it has the most impact.

Before we dive further into edge computing, it's important to recognize and understand the processes that led us to this point. More specifically, how can we now ask questions that allow us to probe the impact of processing data closer to our end user?

## An architecture from the past

Traditionally, when we think of technical architectures, we may imagine a host of computers in one region serving information to visiting users or other machines. This type of architecture is shared amongst various businesses alongside developers and although deployment stratergies have moved from on-prem to cloud, the fundemental idea of deploying services to one geographical location still remains.

Taking a further step back to a time before **"the cloud"** was a thing, if we wanted to run any code that required a server, we would have to run, manage, maintain, and scale our own physical hardware. For small projects, this was no problem as we most often would not run into a scaling issue due to limitations in hardware. However, in the context of larger projects and businesses where scaling was a critical factor, owning physical hardware/servers had a lot of downsides and got expensive relatively quickly.

We can see this depicted in the following example below; toggle between light traffic and heavy traffic to see what happens.

<The_edge_local_infra />

<Aside title="Note" tag="FYI">
  The red dot represents a service that has been deployed to a physical server
  in north america while green user icons are individuals that are making
  requests to the service. Black arrows that originate from the green user icon
  and connect red dot represent a succeful response being returned from the
  server. Black arrows that originate from the green user icon and terminate at
  a red **X** represent an unsuccesful connection to the server.
</Aside>

As "the cloud" became a thing, businesses could now virtualize hardware and later software, therefore, making it easier to approach the scaling problem. The introduction of virtualization provided an abstraction for hardware and software that allowed businesses to move much faster on the development of their product. As a result, there was no longer a necessity for businesses to manage and maintain their own physical hardware. We speak more on the impact of virtualization and containerization in the following article: [What does it mean to containerize an application?](https://www.nonsoo.com/posts/why-containerize). It is important to emphasize that although virtualization solved a lot of problems, limitations still remained.

## The serverless era

Like many, the first time I heard the term serverless I thought that it did not involve any servers. However, this is far from the case; as contrary to its name, **serverless** doesn't actually mean the absence of servers. Rather, it's an architecture that abstracts away the maintenance, and management of a sever. In short, a serverless architecture delegates the responsibility of managing and maintaining servers to someone else, thereby allowing you to focus on the business logic of your application.

### What is serverless?

Serverless architectures encompass many components and can be derived from many abstraction layers, however, they all have one thing in common -- someone else manages the infrastructure. Today, we have cloud vendors like Google, Amazon, Microsoft, etc. that take care of the provisioning and management of infrastructure/resources. The payment structure also works out nicely as development teams are only responsible for covering the cost of their usage -- it's a pay-as-you-go service for servers.

One component when we think of serverless is known as **functions as a service (Faas)** -- colloquially known as serverless functions. **FaaS** is a cloud computing service that enables you to run code in response to requests or events without the need to specify the resources/infrastructure required to run the code.

But wait... you might be now thinking that our definition of **FaaS** is very similar to the definition of **serverless** and you wouldn't be entirely wrong. These terms are used interchangeably as **FaaS** is a central model to the serverless architecture. However, serverless entails much more than just **FaaS** as it involves an entire stack of services that respond to requests or events.

Another component of the serverless architecture is known as **backend as a service (BaaS)**. It's any third-party service that is integrated with your application; think of services like Firebase or Supabase.

<Aside title="Serverless includes much more than FaaS & BaaS" tag="FYI">
  Cloud providers also offer services that are included in the umbrella term,
  serverless computing. These services include Infrastructure as a Service
  (IaaS), Platform as a Service (PaaS), and Software as a Service (SaaS).
</Aside>

Databases can also be included within the umbrella term of serverless since we can now have serverless databases that do not require the provisioning of instances which have a defined capacity, connection and query limit <ToolTip>Think of platforms like PlanetScale, Neon, Cockroach db, MongoDB Atlas, etc.</ToolTip>. Instead, serverless databases move towards models that scale with the demand.

### The scaling problem and optimization?

The introduction of the serverless architecture solved a lot of the previous problems we experienced but most importantly it solved the scaling problem. As we've mentioned, the serverless architecture provided a method to elastically scale services with the needs of our customers as in this case servers could constantly "spin up" and "spin down" to meet the demands of customers. It eliminated the worry of spikes in traffic that could bring down an entire application.

While there are a lot of really good upsides to a serverless architecture, it's not all guns and roses as there are also many downsides to serverless. One in particular is known as the "cold-start" time of a serverless function. Before we explain cold-start times, let's see an illustration to try to figure out what's going on.

**Consider the following:**

Here we have a button that says "**Send request**" which when clicked activates a serverless function. We also have a progress bar that fills up when the serverless function has been activated. Let's press the button to see what happens.

<The_edge_latency_1 delay={20}/>

As we can see, the bar is only filled up a few seconds after the button has been pressed instead of being filled immediately. Now if we were to press the button again, you can see that the bar fills up a lot faster.

Serverless functions are analogous to our example above in that when they are first activated/or called, the environment they are run in needs some time to provision the resources to run the function. This so-called time is known as a **cold start time** and it's one major drawback for serverless functions.

We previously mentioned that serverless functions are very good at spinning up and spinning down to match the demands of our users. So you may now be wondering if serverless functions have to pay the cost of **"cold start times"** whenever they are activated.

In short **yes** but it's more nuanced than that. Recall our example above of clicking the buttons. You may have noticed that if you clicked the button a second time, the bar filled up a lot faster than the first time the button was pressed -- in this case the cost of the wait time was not paid twice. This is very similar to serverless functions as when they are first activated, they pay the cost of the cold start time. However, subsequent activations of the same function within a short period means that the cost of the cold start time is not paid. This occurs because after a function finishes executing, the container/environment required to run the function remains operational for a brief period in case it's needed again. Therefore, we get a **"warm start"** time on subsequent requests that are made to the same function within a short period. Awesome!! Shorter wait times if the function has multiple requests!

But we said that the cost had to be paid again?!?! If we have warm start times on subsequent requests, how is it the case the cost of cold start times is paid again? Recall that on subsequent requests the container/environment required to run the function remains operational and is kept alive. However, once the container is no longer needed (i.e. no new requests are being accepted within a window of time), the container/environment is destroyed. This means that when the function is requested again, the cost of the cold start time is paid again.

We can see this in the following example: Press the button once and then twice to see a warm start time. Wait 10 seconds and then press the button again. What do you notice??

<The_edge_latency_1 delay={10}/>

After we pressed it proceeding with the 10-second wait time, it took a lot longer for the bar to fill up.

## Requests from multiple regions

This is awesome! We've solved the ability for our services to easily scale elastically by moving to a serverless architecture but a bigger issue remains! What happens when function calls are being made from a different region than where the function is deployed? Is there a cost in response time for users?

To properly address this question, we have to recognize that similar to physical servers, serverless functions are mostly deployed to one region. For example, if we were a developer on the east coast of North America, we may opt to deploy our serverless function to the US-east servers. This means that users who live closer to the US-east servers would have faster response times than users who live further away from the US-east servers.

You may recall that we spoke about **edge** being the solution that addresses many of these concerns as it allows us to process data closer to our end-user. Moreover, we introduced the idea of **edge compute** -- the ability to execute code at the edge. Instead of deploying our function to one region, using edge computing, we can deploy our function at the **edge** of many regions.

The image below describes what we mean -- red dots represent edge servers in many regions and green user icons represent an individual user. Black arrows represent a successful connection (request and response) between user and server.

<The_edge_node_deployed />

The image above showcases an edge function (red dots) that has been deployed at the edge of many regions and using this approach ultimately increases the response time for our end-users globally. In turn, it improves the user experience for users who are further away from the original deployed location as they now experience shorter loading times.

<Aside title={`The edge is not just "compute"...`} tag="FYI">
  So far we've been talking about compute -- specifically edge compute. However,
  there is another type of edge that has existed for a while that escapes some
  of the limitations we're about to mention. This type of **edge** is known as
  **edge storage** but it's colloquially referred to as a **CDN (content
  delivery network)**. These edge storage servers are responsible for storing
  and distributing static files at the edge of networks thereby making the
  delivery of content to end-users globally fast.
</Aside>

We can see this demonstrated in the interactive below. When we click on the single deployment (assumes that the services are deployed in us-east) location, we can see traffic to various countries at different speeds. However, when we click on the edge deployment strategy, we can traffic speed up to different countries.

<The_edge_speed_comparison />

You may now be wondering about the downsides of moving to the edge because as we alluded to earlier, it's not all guns and roses.

## The little big things

When we speak about the **edge** in the context of using **FaaS**, we're moving the conversation to computing and executing functions/code at the edge. The downside here is that the resources that are available within a runtime on a traditional server may not be available in an edge runtime. This is the case as it is very difficult to distribute all of these resources across an edge network thus for **edge compute** to exist, the resources needed to make the runtime work have to be very light. [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/web-standards) is a runtime that runs using the JavaScript V8 engine from Google Chrome and they provide access to several standardized APIs through Cloudflare’s global network.

We've mentioned the downsides of moving compute to the edge but to further illustrate them here, let's take a look at some of the APIs we get access to using Cloudflare Workers. The APIs are as follows:

- Fetch
- KV
- Request
- Response
- R2
- Stream
- Web Crypto
- WebSockets

The full list is available [here](https://developers.cloudflare.com/workers/runtime-apis/). Cloudflare Workers are awesome and they allow us to do cool things with edge compute but as we've seen they do not give us access to the full runtime of NodeJS. It's important to note that this example is specifically looking at NodeJS but these limitations extend to other programming languages that require the execution of code at the edge.

Unfortunately, there's more. Yes, there are other downsides of edge computing that are not direct limitations of edge compute. Rather, these are side effects that require other technologies to advance so that we can truly harness the power of the edge on the web! One of these limitations is databases -- specifically when we speak about deploying serverful/serverless databases.

<The_edge_mcq_limitations />

Yes, we run into the exact same issues described above. Our database is deployed to one region (i.e. US-east) and thus the benefits of having the edge are quickly diminished. This is the case as our instance now has to connect from the edge to the database hosted in a specific region, grab the data and then return it to the edge function which then returns it to the the user. We can see this is illustrated in the diagram below.

<The_edge_node_and_db />

When someone from Australia makes a request, that request goes to the edge function nearest to the user -- in this case, it would be Australia (dot in red) -- then the function from Australia makes a database call to servers that are on the other side of the world -- in this case somewhere in Europe, specifically eu-west-1 (dot in blue). We can see that the response times regarding the user receiving the data are relatively longer than what we'd expect using edge compute. This illustrates the need for innovative solutions to optimize data distribution and harness the full potential of edge computing in delivering exceptional user experiences.

## Wrapping up

Sooooo **What's at the edge??** In my opinion, **speed**... speed, efficiency, and improved user experiences are at the edge. The ability to process data closer to our end-users leads us to increase the speed at which they receive information, however, it doesn't stop there! Using edge compute, we can begin to tailor experiences to specific geographical regions. You can imagine an e-commerce store issuing specific gift cards depending on the geographic region a user is visiting from. Going beyond that, full page redirects that are evaluated at the edge are now possible. This unlocks the ability for A/B testing and feature flagging without the addition of third-party scripts or client-side JavaScript. The culmination of these features ultimately improves the user experience of your product as you can now personalize experiences.

By revisiting the architectural paradigms of the past, we see that edge computing builds on top of serverless architectures. While serverless computing excelled in scalability, it faced limitations when serving users distributed across various geographic locations. Edge computing came as a solution as it allowed us to deploy functions closer to end-users globally. This approach promised improved response times and enhanced user experiences, mitigating the impact of geographical distance.

However, we uncovered certain limitations, particularly to do with database location versus edge function deployments. We revealed that longer response times would result if the data was not globally distributed as well. Therefore, we would need to begin to think about having data at the edge and the resulting implications. Some Redis key-value stores are already implementing the idea of having data at the edge to enable localized data stores at the edge. This is similar to the efforts of [upstash](https://upstash.com) with their serverless Redis data platform. However, it would be exciting to see this same implementation for primary databases.

We also stumbled upon resource constraints within edge runtimes. Edge storage, or CDNs, excelled in delivering static content but faced different constraints than compute at the edge. Nevertheless, innovations like Cloudflare Workers offered access to standardized APIs and showcased the potential of edge compute, albeit with certain limitations compared to traditional server runtimes.

Earlier we mentioned that edge computing also had some involvement in IoT devices. Looking specifically at the amount of data generated on these devices, if not processed in real time, it could quickly become overwhelming for centralized cloud infrastructure to handle. Edge computing addresses this issue by processing data at the edge of the network, where it is generated. This allows for quick analysis and decision-making without the need to send the data to a centralized location for processing. Thereby reducing the time it takes for data to be analyzed and acted upon on these IoT devices.

Edge computing and serverless architectures have opened new doors for developers, addressing scalability and responsiveness challenges, while also presenting unique considerations and trade-offs. As we continue to innovate in this space, we must strike a balance between leveraging the speed of the edge and overcoming its limitations to deliver the best possible user experience in our interconnected world.

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article?? Here's a fun little exercise for you to try out! 👀
<The_edge_Exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>Programming</category>
        </item>
        <item>
            <title><![CDATA[Beyond Markdown]]></title>
            <link>https://www.nonsoo.com/posts/beyond-markdown</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/beyond-markdown</guid>
            <pubDate>Thu, 03 Aug 2023 17:29:59 GMT</pubDate>
            <description><![CDATA[Documentation websites play a pivotal role in empowering developers with the knowledge they need to build great products. While traditional documentation tools have served us well, it's time to take a leap forward and elevate the developer experience on our platforms by embracing the power of MDX in our documentation workflows. Join us as we explore how we can leverage the power of MDX to build interactive and dynamic elements directly into documentation hosted on GitHub Pages.]]></description>
            <content:encoded><![CDATA[
## Presentation

<Beyond_markdown_presentation />

## Introduction

In the rapidly evolving world of software development, effective communication and dissemination of information are critical to the success of any project. For developers, documentation websites serve as an invaluable resource, providing the knowledge and guidance necessary to create outstanding products. Today, we have a number of tools that we use to create documentation and they range from services like Notion to GitBook.

<Aside tag="Note" title="Note">
  It should be noted that these aren't bad products!! They serve a purpose and
  have really powerful features! Features such as Git integration, multiple
  environments, easy-to-use collaborative spaces and so much more.
</Aside>

As technology advances, the traditional tools used for documentation have proven their worth, but it is essential to continually explore new methods to enhance the developer experience. Recently, we've been moving towards **"Docs as code"** for a solution to the limitations that the products impose. **"Docs as code"** is a way technical writers & developers create and publish documentation. Moreover, it involves the same tools & processes used to build & ship software.

Embracing **Docs as code** within your teams solves a lot of problems but it only solves a lot of problems for **development** teams. How about the people that are reading the docs? How can we create solutions for them?

One such innovation that can change the way we interact with documentation workflows and solve problems for the readers of our docs is known as MDX. MDX is a superset of **Markdown** that allows us to embed JSX within our markdown content. The [MDXJS website](https://mdxjs.com) puts it best when they say that **MDX** is **Markdown for the component era**.

## Going beyond Markdown

The surprising thing is that **MDX** within our docs is actually nothing new!! Most often, when docs say they support MDX, they tend to just build components that add stylistic elements and a few features. Stylistic elements like the one below are not supported within regular **markdown** or any flavour of **markdown** for that matter.

<Aside tag="Note" title="Note">

<p>

Due to the way DOCS team usually implements <code>MDX</code> you will often only the addition of stylistic elements and a few new features.

</p>
</Aside>

This is really cool and sometimes a necessity but can we do anything else with **MDX**? Recall that **MDX** is a superset of markdown that allows us to embed JSX within our markdown content. The important keyword here is **JSX** -- as it allows us to seamlessly blend the expressive power of React components with the simplicity of markdown syntax.

It allows us to do things like directly embed the quiz component or the live coding environment below directly into our markdown content.

This is really cool but the question then becomes -- How does it help developers?

### DND kit

Imagine we were reading the documentation for a library we want to implement into our project. In this case, let's say we were working with the Drag & Drop library from [DND Kit](https://dndkit.com).

Their documentation is really well laid out in my opinion, however, I think it can be enhanced with the addition of interactive components.

The documentation portion that goes through the different collision detection algorithms gives a detailed explanation of how each algorithm affects the DND system. Although the DND docs provide images for this integration, for some it may still be hard to visualize. To combat this DND kit also has a playground where you can see all the interactions and test all the different configurations of the library. However, this involves you opening a separate window/tab thus it introduces more context switching.

Using MDX, we can embed a live coding playground to see how the code is implemented and also see the result of any changes that are made to the code. Let's look at our implementation below:

<Beyond_markdown_DND_Example />

### Side tangents

MDX also allows you to hide and reveal side tangents. This is very useful in documentation as you the writer gains the ability to include information that would be helpful to the reader but necessary for the particular section. In this case, if the reader already knows the information then they can skip the section but if they want to learn more then they can expand the block quote.

Let's try it out below:

<Aside tag="FYI" title="Testing side tangents">
  This is extra information we are showing you so that you can get a
  better understanding of why components like this are useful.

If you want to learn more about how this is implemented then click the **show more** button!

  <Expanded>In order to get this feature working, we are actually built a react component that shows information when the **show more** button is clicked. You can think of it as a toggle switch... When the switch is off then extra information is hidden and when the switch is on then extra information becomes visible. The **show more** button controls this switch!!</Expanded>
</Aside>

### How we learn

The suggestion to expand on how we include MDX in our docs has a lot to do with how we learn!! There are two common approaches to learning something

1. **Passive learning** -- Quietly absorbing information and knowledge without engaging with the learning material
2. **Active learning** -- Method of learning that ask students to engage with the learning material by thinking, discussing, and investigating the material.

To be fair, when we are using documentation to build products, we actually engaging in active learning. We may often read the docs of a particular product and then try to think about how we could include that feature in our product. We may even discuss it with a colleague or friend or investigate other approaches to working with that feature.

It's really cool that we are already engaging with active learning when working with docs but I think expanding on how we include MDX in our docs will allow us to more efficiently blend the two approaches of learning and bring them into one location -- our **docs**.

## How do we get started?

We've talked about why going beyond markdown is important and the experiences we can create. So the question now is: Where do we begin?

There are two common approaches:

1. We could build our own platform
2. Start from a template

There are different libraries involved with each of these approaches so let's take a look!

### Build our own platform

Within this section there are three popular options that we can go with when integrating MDX into our application. They include:

1. The official way, [@next/mdx](https://www.npmjs.com/package/@next/mdx)
2. Kent C Dodds' [mdx-bundler](https://www.npmjs.com/package/mdx-bundler)
3. Hashicorp's [next-mdx-remote](https://www.npmjs.com/package/next-mdx-remote)

All libraries are really good but personally, I've only experimented with **mdx-bundler** and **next-mdx-remote**.

### Start from a template

We could also start from a template and the involve

1. [Docusaurus](https://docusaurus.io)
2. [Nextra](https://nextra.site)

## How do we deploy

There are many platforms we can deploy our newly created MDX project too and such platforms are/not limited to:

1. GitHub Pages -- using actions
2. Vercel
3. Netlify
4. AWS

Although Vercel and Netlify support one-click deploys out of the box, this can be set up with GitHub pages and AWS as well!

## Wrapping up

I hope you now have a clear understanding of why embracing MDX and going beyond the addition of simple components is a game-changer for documentation websites. Further, I hope that through the presentation and article, I've inspired you to unlock the full potential of MDX to provide an immersive and productive learning experience for developers. Thereby, making documentation a joy to read, use, and contribute to. Together, let's enhance the developer experience and take our documentation to the next level with MDX and GitHub Pages

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article and presentation?? Here's a fun little exercise for you to try out! 👀

<Beyond_exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>conference</category>
        </item>
        <item>
            <title><![CDATA[What's the JSON format?]]></title>
            <link>https://www.nonsoo.com/posts/javascript-object-notation</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/javascript-object-notation</guid>
            <pubDate>Tue, 24 Jan 2023 19:58:28 GMT</pubDate>
            <description><![CDATA[JSON, JavaScript Object Notation, is a lightweight format for storing and retrieving data from across the internet and is most often used in retrieving data from an API. Today, we will take a look at how we can create, and read JSON data we want to send or retrieve from an API. This article explores how we can create and read JSON data we want to either send or retrieve from an API.]]></description>
            <content:encoded><![CDATA[
## Introduction

JSON, JavaScript Object Notation, is a lightweight format for storing and retrieving data from across the internet and is most often used in retrieving data from an API. Today, we will take a look at how we can create, and read JSON data we want to send or retrieve from an API.

## Getting Started

### How do we write JSON?

JSON can either be represented as an array or an object. The following is an example of a JSON object:

```json
{
  "f_Name": "john",
  "l_Name": "Doe",
  "age": 24,
  "school": "UofT"
}
```

This above JSON object defines an object that has four properties:

1. First name
2. Last Name
3. Age
4. Name of the school

One can make the argument that JSON objects are the same as JavaScript objects, however, that is not entirely true. While they do share similarities, there are major differences between the two objects. The keys for JSON objects are always represented by a string and thus the keys are enclosed by quotation marks. Looking at the example above, we can see that all the keys follow this structure.

You may also notice something more interesting -- for the delimiter, we are using an underscore instead of a hyphen or a space. This is done purposefully as in order to use a `JSON` object within JavaScript, the object itself must be serializable. This means that the keys in a `JSON` object must be representative of a valid JavaScript variable thus no hyphens or spaces are allowed.

### Creating a JSON file

We create a JSON file by adding the `.json` file extension to the end of our file name.

At the core anything we put inside of this JSON file, be it a string, number, boolean, etc. is valid JSON, however, we wouldn't want to create an entire file to just store one piece of data. We would more likely want to store several data entries in our JSON file and We can do this in one of two ways:

1. Create an array that stores multiple entries
2. Create an object

## Shape of the JSON

Occasionally you will hear terms like "I need to get the shape of the JSON". This refers to how the actual JSON file is structured/organized. We making an API call, you will almost always see a `data` object where the value for that key is dependent on how the API was designed.

Most often you will see JSON data in the form of an object that has one key-value pair -- the key being `Data` and the value being an array of objects. Looks like this:

```json
{
  "data": [
    {
      "Name": "bob",
      "Age": 34
    },
    {
      "Name": "Smith",
      "Age": 32
    },
    {
      "Name": "Jane",
      "Age": 14
    },
    {
      "Name": "Julia",
      "Age": 24
    }
  ]
}
```

The value of data is represented by an array of objects where each object is essentially a person that has a `name` and `age` property. Storing data like this allows us to store multiple instances of a single object.

You can think of having it on your website, if you wanted to display all the user names for all the users on your website, most likely the API would return a structure like the one above, where each object in the array would be a specific user. This object may have properties like userName, email, Full Name, etc. This userObject returned from the API may look like this:

```json
{
  "userData": [
    {
      "fullName": "Bob Ross",
      "email": "bob@email.com",
      "userName": "bob21"
    },
    {
      "fullName": "Jane Doe",
      "email": "Jane@email.com",
      "userName": "JaneDoe11"
    },
    {
      "fullName": "Stephanie",
      "email": "Stephanie@email.com",
      "userName": "Stephanie--OK"
    },
    {
      "fullName": "Julia",
      "email": "Julia@email.com",
      "userName": "Julia__Apple"
    }
  ]
}
```

## JSON Methods

### Retrieving Data

A common use for JSON is to send/retrieve data from a web API and sometimes the JSON data is sent in the form of a string. Using the user example above, you may see the following after calling an API:

```js
`
{
    "userData":[
        {
            "fullName":"Bob Ross",
            "email":"bob@email.com",
            "userName":"bob21"
        },
        {
            "fullName":"Jane Doe",
            "email":"Jane@email.com",
            "userName":"JaneDoe11"
        },
        {
            "fullName":"Stephanie",
            "email":"Stephanie@email.com",
            "userName":"Stephanie--OK"
        },
        {
            "fullName":"Julia",
            "email":"Julia@email.com",
            "userName":"Julia__Apple",
        },
    ]
}`;
```

Having the data represented as a string is still useable by JavaScript but to get any useful information we would need to use string manipulation to retrieve the information. That takes way too long and we don't want to do that! Since we know that this is an object, we can call a `parse` method on the data to convert it into a JavaScript object.

It looks something like this:

```js
const res = `{
    "userData":[
        {
            "fullName":"Bob Ross",
            "email":"bob@email.com",
            "userName":"bob21"
        },
        {
            "fullName":"Jane Doe",
            "email":"Jane@email.com",
            "userName":"JaneDoe11"
        },
        {
            "fullName":"Stephanie",
            "email":"Stephanie@email.com",
            "userName":"Stephanie--OK"
        },
        {
            "fullName":"Julia",
            "email":"Julia@email.com",
            "userName":"Julia__Apple",
        },
    ]
}`;

const resJSObj = JSON.parse(res);
```

Here we are storing the javascript object inside of the variable `resJSObj` which we can then use to do want ever we want.

### Sending data to API

When we want to send data to an API, we must first convert it into a string. This can be done by calling the `.stringify()` method and then passing in our object. Look something like this:

```js
const sendObj = JSON.stringify(resJSObj);
```

Now that our object is "stringified", we can send it to an API.

<Aside title="Note" tag="Note">
  Turning your JSON data into a string can also be used for storage purposes.
  You can save data retrieved from an API in local/session storage. Not
  advisable but say you wanted to store your users' information in local/session
  storage to keep track of authentication state or user preferences -- you would
  get the data back from the API, convert it into a string and then store it in
  local/session storage.
</Aside>

## Question for you

Now that this is complete we have a way to use the JSON format to send/retrieve information from an API.
Now knowing this, here's a question for you -- how else can you implement the JSON?
]]></content:encoded>
            <author>Nonsoo</author>
            <category>programming</category>
        </item>
        <item>
            <title><![CDATA[Battling CSS style collisions with the superpowers of the cascade]]></title>
            <link>https://www.nonsoo.com/posts/cascade-layers</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/cascade-layers</guid>
            <pubDate>Thu, 12 Jan 2023 05:01:54 GMT</pubDate>
            <description><![CDATA[We've all experienced CSS style collisions in our codebase when writing new styles or adding new 3rd-party styling libraries. This can make working with CSS incredibly frustrating sometimes! However, there have been some new additions to the CSS spec that makes working with the cascade a bit easier. This article explores cascade layers and how they rework our approach to organizing and structuring styles within CSS.]]></description>
            <content:encoded><![CDATA[
Understanding the cascade is an important part of learning CSS, and it's the unsung hero of conflict resolution on the web. However, it can also drive CSS authors to frustration, as it may be the reason that some CSS properties may not work as expected. To put it in context, the cascade is the reason that a text colour for a button can be rendered even though multiple definitions may exist.

<Cascade_Layers_SelectionParagraph />

We have a paragraph element above that we are selecting in three separate ways using CSS:

1. Just the element selector
2. An element selector that has the `!important` rule
3. A class selector

How does the browser know which style to apply? Is it the first, second or third option? When multiple CSS selectors for the same HTML element exists, the cascade is what governs which of these selectors takes precedence, as the algorithm is designed specifically to resolve this conflict. It looks at all the selectors for a given element and, through a defined algorithm, it selects which rule will be applied.

<Cascade_Layers_FirstPlayground />

The definition of the CSS cascade that I like comes from [Bramus](https://bram.us) another web developer. It goes, "The CSS cascade is an algorithm that determines the winner from a group of competing declarations". **Competing declarations** is the important part here because as we alluded to above, there are multiple ways in CSS to select the same element.

<Aside title="The CSS Cascade Algorithm" tag="FYI">
    The cascade algorithm is split into 4 stages:
        1. **Order of appearance** -- Where does the rule appear in your style sheet? The order of the rules
        2. **Specificity**: An algorithm that determines which CSS selector has the strongest match
        3. **Origin**: Where does the CSS selector come from? Is it the browser that is setting the rule, an extension, or authored style
        4. **Importance**: Does the rule have the !important rule attached to it?

    These four rules are used to determine the winner from a group of competing declarations thereby preventing conflicts about what styles are applied to an element. This [article](https://web.dev/learn/css/the-cascade/) walks you through the intricate details of the CSS cascade algorithm. Amelia Wattenberger also has an incredible [article](https://wattenberger.com/blog/css-cascade) going over the CSS cascade.

</Aside>

Even with a working knowledge of the cascade, we've all experienced **CSS style collisions** in our codebase when writing new styles or adding new 3rd-party styling libraries. This can make it incredibly frustrating to work with CSS sometimes. However, there have been some new additions to the CSS spec that makes working with the cascade easier.

Cascade layers allow CSS authors (developers) to add layering to CSS declarations. In short, they rework how we approach organizing and structuring declarations within our CSS files, thereby limiting conflicts and giving the developer a bit more control over the cascade.

Before we dive into cascade layers, let's go through a quick primer on the CSS cascade.

## Primer

We've established that the cascade algorithm's job is to determine the correct values for the CSS properties when there are multiple selectors/declarations for the same element. The algorithm has many criteria -- one being the position/order of appearance of the declaration. CSS declarations that appear further down in the CSS file have higher priority than declarations that appear near the beginning of the CSS file -- we are assuming the declaration are for the same element.

CSS declarations can be made from multiple origins, therefore to properly determine the correct value for a CSS property when there is a conflict, the algorithm must be able to decern which origins have higher priority. Let's bring your attention back to the definition of the cascade algorithm, more specifically let's focus on the origin rule. This rule alludes to the fact that style sheets can originate from different origins (**These are known as cascade origins**) and they include: (listed in order of precedence from low to high)

1. User-agent styles
2. User styles
3. Author styles

### User-agent style

**User-agent** styles, better known as **browser styles**, establish the default styles for an HTML document and they are written by browser vendors. Although some browsers allow users to modify user-agent styles, it is very rare and not something that can be controlled. For this reason, you will find that brand-new HTML files that do not have any authored CSS linked, still have styles that are being applied in the browser. Elements such as headers, and paragraphs may have padding or margin added to them even though you did not specify it. Moreover, these styles are browser specific, therefore, they may be implemented differently across browsers. A range selector in Google Chrome may look different in Safari or Firefox, and it is a result of different styles being applied by the browser.

Unless the user-agent stylesheet includes an `!important` rule next to a property, any CSS declaration in the Author style or User styles can override declarations in the user-agent styles.

![devTools showing user-agent style](cascade_layers_devtools)

Looking at the browser dev tools, you will be able to see the styles that are defined by the user-agent style sheet. Most often, they will be crossed out if they are overwritten by author or user styles.

### User styles

The user stylesheet consists of styles written by a user for a specified website and they can be used to override user-agent styles. User styles can be modified/configured directly or added via browser extensions.

### Author styles

Author styles are the most common type of style sheets that you will come across as these are the style sheets that are written by web developers. Author styles have a higher priority than user-agent styles and thus can be used to reset any styles set by the user-agent. In addition, author styles can also define the styles for the design of a given web page. As you may recall, user-agent style sheets are sometimes different across browsers, thus to ensure consistency you will often see CSS resets/normalization being added to a project. CSS resets, undo all or most default styles and creates a blank slate. A reset may look something like this:

```css
*,
*::before,
*::after {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
```

This reset is setting the padding and the margin on all elements to 0 including the `before` and `after` pseudoelements. It is also setting the box-sizing to **border-box**, therefore, the border is taken into account when calculating the width of a container. There's a lot more that goes into a CSS reset, and there're many different ones -- here's one [reset](https://meyerweb.com/eric/tools/css/reset/) that I find is used quite frequently. Although CSS resets are a good thing to have in your project, I do find that they may not be needed as much anymore. Browsers no longer have massive discrepancies when it comes to layout or spacing since they implement the CSS spec very similarly so things behave as you'd expect.

Author style sheets can be written in different ways:

1. Inline -- defined using the style attribute on an HTML element
2. Internally -- using the style tags in an HTML document
3. Externally -- CSS document is linked/imported into an HTML document

<Aside title="Note on writing styles" tag="Note">
  It's important to note that the method chosen to write the author styles also
  has implications on the specificity of the selectors for an element. Inline
  styles take precedence over internal and external styles while internal styles
  take precedence over external styles.
</Aside>

## The problem

Cascade origins help with the organization and balancing of styling concerns across different agents (style sheets that are setting styles). As we've seen above, it allows the cascade algorithm to discern which declarations take priority. Although it's awesome that we have this separation of layers between different origins, it may be useful to have this same layering of concerns when working within the same origin. Let's take the author styles for example -- as we alluded to above, we often first apply CSS reset/browser normalization and then add styles that fit our design system. This **apparent** layering of concerns means that we have to be aware of the selectors we choose so as not to run into a specificity battle later on. This also means that we are forced to carefully manage selector-specificity or use the `!important` flag for overrides to get things to work as expected.

<Aside title="Causion" tag="Note">
  Be very careful using the `!important` flag because it's often & easily misused,
  and it can lead to more unexpected side effects.

  <Expanded>
    As you may have noticed above, **importance** is one of the last rules that is evaluated by the cascade algorithm. Since it is evaluated after specificity, a property that is marked as `!important` can be very tricky to override.

    Important declarations reverse the order & precedence of cascade origins and layer order. This means that user-agent styles that are marked as **important** will have a higher precedence than any other style from any other origin. Similarly, important declarations from the user style sheet take precedence over styles in the author style sheet.

    This reversing of the order of precedence is done intentionally as it ensures a few things. 1) Ensures that accessibility concerns can be fully met and that 2) styles that may break the functionality of the browser cannot be applied.

    You may be wondering if anything can override important declarations. Yes, CSS transitions can override important declarations.

    For more info, the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/CSS/important) on this topic is a great resource!

</Expanded>

</Aside>

We can use conventions such as `BEM`, `ITCSS`, or `OOCSS` to try to alleviate the occurrence of specificity battles, however, the issue of carefully managing selector-specificity still remains.

**Is there another way???**

## Cascade layers

Cascade layers allow for the balancing and organization of styling concerns within the same origin and its part of the [CSS Level 5 specification](https://www.w3.org/TR/css-cascade-5/). As you may recall, we mentioned that cascade layers allow CSS authors (developers) to add layering to CSS declarations. It's important to note that **we are not talking about visual layering** which is often seen with the **z-index**. Rather, cascade layers **refer to the way we structure our CSS code**. We are reworking how we approach organizing and structuring declarations within our CSS file thereby limiting conflicts and thus taking back some control over the cascade.

To begin with cascade layers, we first use the `@layer` property to tell the browser that we want to define a new layer. We can now specify CSS declarations inside the layer. The added benefit is that declarations that are added to a layer are now scoped to that layer. I, however, say "scoped to that layer" with a grain of salt as this is different from **scoping** in CSS -- more on this later.

Cascade layers can be written in a couple of different ways but to start us off, we'll look at how we can define a layer and then write rules inside our layer at the same time. The following code block describes how we can do this:

```css
@layer reset {
    .main{
        something goes here
    }
}
```

You can see that it's like using another `@` rule in CSS. The `@layer` property is followed by an optional name parameter -- in this case `reset`. Layers can either be named or they can remain anonymous. **Named layers** have a name/identifier that follows the `@layer` property while **anonymus layers** do not have this parameter. For this reason, named layers can be referenced multiple times in multiple locations and it allows us to merge styles into layers that have the same layer name. Since anonymous layers do not have the name parameter, they cannot be referenced later on thus merging of styles cannot occur with these types of layers. Anonymous layers look like the following:

```css
@layer {
    .main{
        something goes here
    }
}
```

You might now be wondering if we can reference **named layers** multiple times, then what sets the order and precedence of a cascade layer?

Similar to the order & precedence of CSS style rules, the order & precedence of a cascade layer is set in the order that they appear. To be specific, layers that appear last will always have higher priority than layers that appear near the beginning -- an increasing priority. In our demo below, we've defined a couple of cascade layers in our CSS file. Let's see what happens to the font size of the text when we move the `base` layer to the bottom of the CSS file

<Cascade_Layers_SecondPlayground />

As we can see, when we move the `base` layer below the `main` layer, the size of the text becomes smaller. This occurs because the `base` layer now has higher priority/precedence over the `main` layer. So if this is how we set the order & precedence of cascade layers, wouldn't we have to keep track of where we define our layers if they are defined across multiple files? Moreover, wouldn't we have to make sure that the file that contains the `base` layer is imported before the file that contains the `main` layer?

In short, **yes**. However, there is another approach that allows you to set the order & precedence of cascade layers before you define the styles that are associated with the respective layer. The `@layer` rule can be used with only an identifier/layer name to define a layer without attaching any style rules. This is useful for establishing a layer order in advance. It looks like the following:

```css
@layer base, main;
```

Recall that earlier we were speaking about named layers being able to be referenced multiple times in multiple locations and that a merging of styles would occur for layers with the same name. This is possible because with layer-names that match an existing layer defined in the same layer-scope and origin, will assign the style rules to the existing layer. Effectively, we are first defining the layers without setting any style rules to set the order & precedence of the layers. We can then reference the layer name and set the style rules for that layer. We do not have to worry about the order in which we set these layers with style rules as the layer has already been defined. The style rules defined will then be assigned to the existing layers. This only works with named layers and it is **important** that the names remain the same as any new layer name defined will automatically have the highest priority.

This demo is similar to the one above as we've defined a couple of cascade layers in our CSS file. However, we have also defined the order & precedence of the layers -- this is seen on the first line of the CSS file. Let's see what happens to the font size of the text when we move the `base` layer to the bottom of the CSS file.

<Cascade_Layers_ThirdPlayground />

As we can see, when we move the `base` layer below the `main` layer, the size of the text does **not** change. This occurs because the priority/precedence of the `base` layer does not change even though we've moved the `base` that defines the styles. The order & precedence of the layers is set at the very top of the file. This would still work if the `base` and `main` layers that have styles defined were in separate files. We just have to make sure that the file that sets the order & precedence for all the layers is imported first.

### Layering CSS imports

With cascade layers, you have the ability to import CSS libraries and put them inside a layer! In my opinion, this is just awesome! You may have found that it can be frustrating working with CSS libraries when you are trying to override certain rules set by the library. The documentation of some of these libraries doesn't explicitly tell you this but sometimes they use highly specific CSS selectors, therefore, it may be nearly impossible to override some of these rules. This issue is no longer the case with cascade layers as we can import libraries such as Bootstrap, Material UI, or other libraries, and place them inside of a layer. The layers we define later on will have a higher precedence than our libraries layer, therefore, we now have the ability to easily override selectors in these CSS libraries.

The following code block is showing us how we may import a CSS file and assign its styles to a layer:

```css
@import url(bootstrap.css) layer (library);
@layer base, main, table;
```

As stated above, the `base` and `main` layers will take precedence over the library layer. An alternative approach would be to define all the layers first and then do the imports. Using this alternative approach means that the order in which you `@import` your styles won’t matter to the layer order, since the order of the layers is already established.

### Nesting Layers

Sometimes we may want to nest layers within layers when using cascade layers as layer names may start to become verbose and repetitive. For example, let's take the `main` layer we defined in our last code block -- we can nest a `reset` layer inside of the `main` layer. It looks something like the following:

```css
@layer main {
    @layer reset {
        things go in here
    }
}
```

To access the `reset` layer inside of the `main` layer, we combine the two-layer names and separate them by a period. It looks like the following: `@layer main.reset`. Further, layer names are scoped to their surrounding layer, therefore, you will not run into name conflicts if you have a nested layer name that is the same as an un-nested layer name.

## Order of precedence for everything

So far we've reviewed the cascade and how the cascade algorithm works, the problems that may arise and the patchy workarounds that exist. We've also gone over the role of cascade layers and how they attempt to solve some of those problems. However, there is one more question that remains to be answered -- When the cascade algorithm analyzes the order & precedence of styles in the browser, where do cascade layers fit in that order? **Recall cascade layers are most often defined in the author styles/origin**.

**Una Kravets** has an incredible depiction of the order & precedence of layers and cascade origins over at the [chrome developer blog ](https://developer.chrome.com/blog/cascade-layers) and it's also the following image below:

![Order of precedence for overall styles](cascade_layers_order_precedence)

The order of precedence from lowest to highest is as follows:

- User Agent **normal**
- Local user **@layer styles**
- Local User styles **normal**
- Author styles **@layer**
- Author styles **normal**
- Author styles **!important**
- Author styles **@layer !important**
- Local User styles **!important**
- User Agent **!important**

You may notice that the above list does not include nested layer styles and thus you may be wondering where those fit in. Nested layer styles have less precedence than their parent layer, therefore, declarations in a parent layer will override declarations in a nested layer.

Recall the example code blocks we've listed above -- So far we have:

```css
@layer reset, library, base, main, table;

@layer main {
  @layer reset {
    /*stuff goes here*/
  }
}

@layer {
}

.otherStyles {
}
```

Let's take a look at the order & precedence of those layers. This is listed from lowest to higher and it's as follows:

- reset
- library
- base
- main.reset
- main
- table
- Any anonymous layers defined
- unlayered author styles

It is important to note that **unlayered author styles** will almost always take precedence over any layered styles that are defined. According to some developers within the CSS working group, this was a very debated topic, however, it was done intentionally. Apparently, it allows developers to have the confidence that their styles will always be applied when they are using style sheets that implement cascade layers -- developers do not need to battle with the order of appearance of styles when importing external style sheets.

Further, I say unlayered author styles will **almost** always take precedence because of the `!important` keyword being used with layered styles -- more on this later.

## The little big things

With any tool in general, you may benefit from knowing about the nuances of the tool before diving into using it. This is no different with cascade layers!

### Order & precedence

In the order & precedence section, you may have noticed that `@layer !important` styles have higher precedence than non-layered (normal) styles. While layered styles have lower precedence than unlayered styles in general, using the `!important` rule inside of a layer results in the layer becoming more specific than unlayered styles. Further, if you have multiple layers, the first layer with `!important` flag would become the layer that has the highest precedence. This is the case as the `!important` keyword **inverts** the order & precedence of the layers.

```css
@layer base, main, table;
```

Looking at the code block above, the order & precedence would follow the order in which the layers were listed -- with the `base` layer having the lowest precedence and the `table` layer having the highest precedence. However, if the `base` layer had styles that were using the `!important` flag, it would mean that those styles would now have higher precedence than their counterparts in the `main` and `table` layers.

### Specificity & Layers

With cascade layers, a less-specific selector, like an element selector, will override a more-specific selector, like a class selector, if that less-specific selector is inside a more specific layer. For example, if we were using an element selector in our `main` layer and a class selector in our `base` layer, then the styles from the element selector in our `main` layer would be rendered to the browser.

**Pop Quiz!!**

<Cascade_Layers_SpecificityQuiz />

### Scoping

We previously talked about how cascade layers do not solve the scoping issue in CSS. To further expand on this, if you have a CSS file using the `@layer` property to apply styles to a component, using an element selector will **not** scope those styles to that component. Rather, the styles will be applied to all instances of that element. Therefore, it remains important that we scope our styles correctly.

## Wrapping up

As the name suggests, the cascade is one of the things that define how CSS works and the algorithm behind it is integral to resolving conflicts that exist. Therefore, it's important that CSS authors have an understanding of how the cascade works and how it approaches conflict resolution. As we've seen, without this understanding, the cascade can drive CSS authors to frustration, as some style overrides may not work as expected.

Luckily, the new CSS specification implements a new rule that allows CSS authors (developers) to have a bit more control over the cascade. The introduction of cascade layers allows for the balancing and organization of styling concerns within the same origin. As we've seen, developers have the ability to organize their styling rules into layers so as to limit styling conflicts and ensure that things work as expected.

There are a lot of cool things that can be done with cascade layers but sometimes we may want to roll back to styles that are defined in the user-agent origin. Moreover, we may also want to roll back to styles defined in previous cascade layers. The `revert` and `revert-layer` keywords can help us accomplish this and **Una Kravets** has an incredible [video](https://www.youtube.com/watch?v=2wSckPwaC_A) going over how these keywords work.

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!

## Practice problems

**PSSSST! Hey you! Yaa you!** Enjoyed the article?? Here's a fun little exercise for you to try out! 👀

<Cascade_Layers_Exercise />
]]></content:encoded>
            <author>Nonsoo</author>
            <category>css</category>
        </item>
        <item>
            <title><![CDATA[Thinking about a new responsive web]]></title>
            <link>https://www.nonsoo.com/posts/container-queries</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/container-queries</guid>
            <pubDate>Thu, 15 Dec 2022 05:04:44 GMT</pubDate>
            <description><![CDATA[Design on the web has changed drastically over the years. Tools such as media queries, flexbox, and CSS grid allow developers to reshape layouts on the web to suit the devices of many users. Although we are still iterating and uncovering answers to questions that drive the user experience on websites, the shift to component-based development has made it increasingly important to think about how components define their own layout. This article explores container queries and how they iterate on the idea of micro-layouts.]]></description>
            <content:encoded><![CDATA[
Design on the web has changed drastically over the years; So much so that we now have the tools to build on ideas that we once thought were impossible. It's an exciting time to be a front-end developer, and I don't say this lightly! There was a time when structuring layouts on the web was very tedious, and implementing responsive layouts was not even a question in mind. Developers were forced to build multiples website to ensure that desktop and mobile users had a great user experience when visiting a website.

It's important to remember that user experience drives the design of user interfaces, and layout is a critical component of those interfaces. Therefore, as the complexity of those interfaces grows, so do the options for designing layouts for them.

Let's think about the following questions as they relate to responsive layouts:

- How does the layout of a page respond when the size of our viewport -- our canvas in which our website is built -- changes? At smaller screen sizes, are we putting more important information at the top or are we showing a zoomed-out version of the page?
- What happens to the size of elements on the page with a change in viewport size?

There was a time when questions like the ones above were difficult to answer, but the introduction of the responsive web, allowed us to begin uncovering the answers to those questions.

## A look at where we are

Tools such as media queries, flexbox, and CSS grid allowed developers to reshape layouts on the web to suit the devices of many users. Media queries brought us the ability to query the size of the viewport, thereby allowing us to modify the CSS properties on DOM elements with a change in viewport size. This addition meant that we could now show/hide and even re-order DOM elements based on the viewport size.

Let's imagine that this box is our viewport. As we make the size of this viewport smaller (dragging the slider), we begin to see a layout shift -- Elements that were once in rows are now put into columns, and elements that were once present are now hidden.

<ContainerQuery_ViewportEx />

This can be observed on any modern website, including this one! Try changing the size of your web browser!

Flexbox brought about the idea of flexible containers and items, and it allowed us to explore what happens to the intrinsic size of an item as the available space changes. Our options grew as we could now begin to wonder how elements could distribute the available space to properly fit within the viewport. Thereby allowing us to ask deeper questions about what it means to have a more flexible/fluid layout. This is of course in addition to our ability to hide elements or move to a column layout at smaller screen sizes with media queries. Josh Comeau has an incredible [article](https://www.joshwcomeau.com/css/interactive-guide-to-flexbox/) that explores Flexbox and its awesome quirks -- it's worth the read!

CSS grid, commonly known as Grid, brought about the idea of a two-dimensional grid system that redefined our approach to developing user interfaces. It allowed us to think of our page as a grid system, thereby making the elements on our page items on that grid. This allowed us to forgo workarounds for implementing certain layouts, as now we could place items anywhere within our predefined grid system. As with Flexbox, CSS grid is another tool in our arsenal that we can use in conjunction with media queries and Flexbox to create responsive layouts.

Although we are still iterating and uncovering answers to questions that drive the user experience on websites, the shift to component-based development has made it increasingly important to think about how components define their own layout. This can be defined as **macro** & **micro** layout; **macro layout** being the layout that defines the overall page structure/layout and **micro layout** being the layout that defines the intrinsic layout of a component. The tools described above have allowed us to iterate on macro layouts but as development has shifted towards more component-based layouts, we have to iterate on development with micro layouts.

## Container queries

Container queries iterate on the idea of micro layouts, as they allow us to set a defined container and have the children query the size of the container. Similar to media queries, container queries allow us to modify the CSS properties on DOM elements, thereby allowing us to show/hide, re-order DOM elements, and modify other properties based on the size of a container. An important distinction to be aware of is that **media queries** allow us to query the size of the viewport, whereas **container queries** allow us to query the size of a defined container.

Container queries move us beyond considering only the viewport, and allow any component or element to respond to a defined container’s width -- Stephanie Eckles.

This solves a unique problem in that container queries allow us to develop components that are intrinsically responsive. This allows us to have confidence that we can build a component once, but use it anywhere. More specifically, a component that is used in the main section of a web page can now be put in a sidebar without adding any additional utility classes that target the component in the sidebar.

Let's check out the example below in which we've defined some components that make use of container queries.

<ContainerQuery_QueryEx />

We can see that the same component is being rendered differently depending on the available space. When there is not enough space, the black box and text stack. But when the space becomes wide enough, the black box and text can now be side-by-side and the title can have a bold font weight.

## Getting started with container queries

Container queries were recently introduced into the CSS spec, and as of the time of writing, they are available for use across the major browsers. The first step to getting container queries to work is by setting containment on a parent element. Containment allows developers to tell the browser what parts of the page are encapsulated as a set, thereby providing isolation of a DOM subtree from the rest of the page. Moreover, it's hinting to the browser which parts of the page can be treated as independent, therefore, setting containment on an element enables browsers to isolate queries for that container. Four types of containment can be set on an element, and they include:

1. size
2. layout
3. style
4. paint

If you've been following the formation of the container query spec then you may recognize that the `contain` property was used to define a container. Using the `contain` property, you would have to set `style` `layout` and `size` containment at the same time to properly define the container. However, there have been revisions in the container query spec and it's now a lot simpler to set containment on an element. `container-type` allows us to specify the `size` containment on an element, while the `style` and `layout` containment are automatically added.

Let's say that we had the following HTML snippet, and we wanted a section that appears both in our main section and inside a sidebar:

```html
<main>
  <section>...</section>
  <section class="container">...</section>
  <section>...</section>
</main>
<aside>
  <section class="container">...</section>
</aside>
```

In our CSS we would select our section that has the class of container and set our `container-type` property on this selector. Since `container-type` is a shorthand for setting the size containment, it has one of three values:

1. inline-size - Establishes queries on the **inline axis** of a container.
2. size - Establishes queries on both the **block** and **inline** axis of a container.
3. normal - **Does not** establish a query container for any container size queries but remains a query container for style queries.

Since we only want to query for the width of the container, we're going to set the `container-type` to inline-size.

<Aside title="Things to be careful about" tag="FYI">
	By setting `container-type` to inline-size we are telling the browser that the **container itself** and **not its children** is responsible for setting its size in the inline direction. This means that we have to explicitly specify the size of the container in the inline direction. For the English language, this would be the width of the container.

    However, when we change the `container-type` to size, we are telling the browser that the **container itself** and **not its children** is responsible for setting its size in both the inline and block direction. This means that we have to explicitly specify the size of the container in both the **inline** and **block** directions. For the English language, this would be the width and height of the container.

    Most often we will be using the inline-size when setting the `container-type` on an element.

</Aside>

Although optional, we can also name our container with the `container-name` property. This may come in handy if we were dealing with multiple containers or even nested containers. A nice shorthand for both the `container-type` and `container-name` is the `container` property. Using this property, we can specify the `container-type` and `container-name` in a single line. It's as follows:

```css
.container {
  container: container-name / container-type;
}
```

Now that we've defined our container, we can begin writing our queries to set styles for the children. A queried element will use its nearest ancestor that has containment applied. This is important to keep in mind because nesting containers is possible and, as you may recall, we were speaking earlier about how the `container-name` property may come in handy when nesting containers. Further, if we are trying to query a container when there are no containers defined, then the query itself would be disregarded. It will fall back to the version of the styles applied to elements before the query.

So, how do we write a container query? As I alluded to above, container queries are similar to media queries, and these similarities extend to their syntax. Container queries begin with `@container` and are then followed by the optional container name and then the query parameter. It looks something like this

```css
@containter optional-name-parameter (min-width:300px) {
  ... things go in here;
}
```

It's important to note that we are querying against the computed `min-width` rather than the defined style of `min-width` -- this may be useful when setting a `container-type` on an element that is a flex item or a grid item. Furthermore, the rules applied inside a container query only affect the descendants of the container and not the container itself -- ie/ containers cannot query themselves. Going back to the HTML markup above, we cannot apply rules to the section that has the class of container if that element is a container, and is being used to set a query. However, we can apply rules to the descendants of elements inside the container.

Let's take a look at what writing a container query would look like for a card component:

{/* A card demo that shows two cards with different styles being applied depending on the width of their container -- Use sand pack */}

<ContainerQuery_Playground />

Looking at the CSS file, we can see that we've set containment on the element that has a class of **card**. We're now going to be querying the container to apply some styles when the container is larger than a certain size -- in this case when the width is greater than 300px. Here we are changing the flex orientation to a row and using a larger font size. This is so awesome because this is now an intrinsic layout as we're specifying styles based on the size of the container rather than the size of the page.

<Aside title="Structuring our queries" tag="FYI">
  The container/media query similarities also extend to the way we approach
  structuring the queries. There are many different thoughts and approaches to
  properly structuring queries but I find adopting a "mobile-first" approach is
  the most intuitive. I say "mobile-first" as we can start with the smallest
  layout as the default and then progressively query on larger container sizes.
</Aside>

Earlier we mentioned that a container cannot query itself, however, a container can be used as part of the CSS selector for its children. Meaning that you can use a container as a compound selector or a way to select its descendants.

## Container queries in a flex or grid layout

When working with flex or grid layouts, it may be tempting to think of flex/grid containers as the container in which you want to query to change styles within the flex/grid item. Although doing this may be useful in some situations, in most situations it often yields unexpected results. Most often, the flex/grid container is part of the overall page layout, which then responds to the size of the viewport. Therefore, putting a `container-type` property on a flex/grid container that is part of the overall page layout makes the container query act more like a media query. This is the case as the computed width of those flex/grid containers only changes as the size of the viewport changes.

We're now in this catch-22 as:

1. We can't put the `container-type` property on elements that we want to style as a result of our query -- IE/ containers can't query themselves
2. We may end up creating a container query that acts more like a media query

How do we solve this? 🤨

We're going to put the `container-type` property on a flex/grid item, however, the flex/grid item may not be the element that you think.

```html
<main>
  <section class="container"><p>...</p></section>
  <section class="container"><p>...</p></section>
  <section class="container"><p>...</p></section>
</main>
```

We're going to wrap our elements in a wrapper class which then becomes the flex/grid item to which the `container-type` property is added. To be specific, `main` would be a flex/grid container while `section` elements with the class of container would have the `container-type` property added in CSS.

We spoke a bit earlier about using the `container-type` property with elements that were either a flex item or a grid item. Moreover, we established that the container query parameter uses the computed width rather than the defined style width. This rule is especially important for `flex-items` as the width or flex-basis that is set for that item is more of an idealized value -- Josh Comeau speaks about this more in this [article](https://www.joshwcomeau.com/css/interactive-guide-to-flexbox/). Therefore, when querying for a width of 300px, the query parameter is going to be looking at the computed width of the flex-item rather than the width or flex-basis that is set on that item. This is also important for `grid-items` in which the column size is set using the `fr` unit.

Pop Quiz!
<ContainerQuery_Quiz />

I think it's important to be aware of the relationship between containment and flexible items, especially as we've moved from rigid layouts to more fluid and flexible layouts. It's weird to think about, as container queries have removed intrinsic sizing on elements that have a container defined. But if those elements are also flexible, then they retain the ability to grow and shrink, thus the container itself is now flexible. I think this establishes a new dimension that adds to the fluidity of micro-layouts, as components that define their own layout can now respond to their environment.

Consider the following - Drag the slider to change the width of the container and observe what happens to the layout of the cards. Just so you're aware, each of these cards is a flex-item.

<ContainerQuery_FluidLayout />

## The little big things

Container queries have some side effects that would be useful to know. We spoke a bit earlier about how setting containment on an element allows developers to tell the browser what parts of the page are encapsulated as a set, thereby providing isolation of a DOM subtree from the rest of the page. Since setting containment also includes setting layout containment, we are telling the browser that everything needed to construct the layout of this element and its descendants is scoped within the element itself. Meaning that the browser does not have to look outside that element to know how to construct the layout for that element and its descendants.

Having the layout scoped to the element means that we establish a new **formatting context** thus no more collapsing margins. This is similar to layout algorithms like flex and grid in that these algorithms do not have any collapsing margins aswell. Further, the element that gets containment will also be the **containing block** for fixed and absolutely positioned elements -- this is similar to putting `position:relative` on a parent element. You also create a new **stacking context**, so you now have the ability to use the `z-index` property.

Container queries also introduce a range of new units that add to the fluidity and flexibility of a container. These units are similar to viewport units in that they are relative units but instead of being based on the size of the viewport, they are based on the size of the container. These units include:

- **cqw** for the container query width unit
- **cqh** for the container query height unit
- **cqi** for the container query inline-size unit which specifies the size in the inline direction
- **cqb** for the container query block unit which specifies the size in the block direction.
- **cqmin** is a container query unit that picks the smaller value of either `cqi` or `cqb`
- **cqmax** is a container query unit that picks the larger value of either `cqi` or `cqb`

<Aside title="Caution" tag="Note">
	For the container query units, if there is no container defined then units will be looking at the viewport for a definition. **This means that 1cqw will equal to 1vw.**

    Further, if your `container-type` is set to **inline-size** then **cqb** will act like a viewport height since it is unaware of the height of its container. This changes if `container-type` is set to **size**. Moreover, **cqmin** and **cqmax** start working properly if the `container-type` is set to **size**.

</Aside>

I want to bring your attention back to the demo above -- the demo with the user cards and slider. If you look closely, you'll notice that the font size of the name changes as you change the size of the container. This is really cool because now we can create variable fonts sizes that are scoped to the size of the container. Variable font sizes have been a thing for a while because of the introduction of viewport units, however, we can now make these font sizes respond to the size of the container rather than the viewport. This is made possible by the container query units.

The impressive thing is that this variability is not limited to just the font size. We can also create variable padding and margin sizes. We may want small amounts of padding when the container has limited space, but as we increase the available space inside the container, we may also want to increase the padding as well.

## Wrapping up

Design on the web has changed drastically over the years as we've moved from intuiting hacks that solve obscure problems about layout on the web to an era of responsive design. These problems and hacks have allowed us to think about what it means to have a webpage that responds to the type of device it's presented on -- bringing about layouts that move away from rigidity, and towards fluidity. We're now in a new era of design on the web!

Jen Simmons said it best when she said, **"we're now in the era of intrinsic design"**. Container queries are something special as they allow us to think about what it means to have a responsive component. Moreover, they've allowed us to overcome the last hurdle of what it means to have a component design system, as components can now own and define their own layout. **We can now truly create a component once, but use it everywhere!**

Container queries however do not stop at querying for just the size of the container. Just as media queries now allow us to query for user preferences, in the future we may be able to query for more than just a containers size. There is experimentation being done on what it means to query the style or state of a container. If a container has a certain style or is in a certain state (is the container currently stuck or not?), what styles can we apply to its children? Geoff Graham explores container style queries in the following [article](https://css-tricks.com/digging-deeper-into-container-style-queries/) and Ahmad Shadeed's new [article](https://ishadeed.com/article/css-container-style-queries/) diagrams different use cases for style queries.

It's an exciting time to be a frontend developer, as the future of design on the web looks bright and exciting!!

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>css</category>
        </item>
        <item>
            <title><![CDATA[What does it mean to containerize an application?]]></title>
            <link>https://www.nonsoo.com/posts/why-containerize</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/why-containerize</guid>
            <pubDate>Thu, 01 Dec 2022 16:03:42 GMT</pubDate>
            <description><![CDATA[Setting up another development environment can be a tedious landscape to navigate. It slows the build process as you first have to set up all the dependencies. Moreover, in a production setting, those same dependencies must be set up before your application becomes accessible. This article explores what it means to containerize an application and why developers may want to opt into this approach as their application grows.]]></description>
            <content:encoded><![CDATA[
<With_Container_SVG />

You've just finished writing the code for an exciting new application and you're ready to share it with the world. You remember that before you can launch your new application, you have to do your due diligence, and test the application to make sure that it works as expected. You then write and complete the unit tests, integration tests, and even end-end tests and find that everything passes. You even go as far as testing the application on a friend's computer and find that everything seems fine. You now have confidence that your application is ready to be deployed to production servers and so you begin the process of deployment.

A few moments later you realize that your code is not working on the production servers. Confused as to why the code is not working in production, you begin diagnosing the issue and after a dreaded few hours, you find that your code is incompatible with the version/run time environment on your production server. The version of the run time environment between your computer and the production servers differs on a level that prevents your code from executing on the server. Excited about finding the issue causing this setback, you quickly upgrade the production environment and successfully deploy your code. Your application is now out on the interweb for everyone to enjoy!

I'm sure many developers have had a similar experience to the one described above but interestingly it's a situation that some developers won't experience until it comes time to deploy their code to a production server. To clarify, I'm not speaking of applications that take advantage of services that offer what I call one-click deploys -- deploys that occur directly from your git-repo. While these services are very useful and make it easy to deploy an application, they may lead to vendor lock-in in the sense that it becomes difficult to move an application from one platform to the other. Rather, I'm speaking of applications in which we want to retain this autonomy and have the freedom to move to another platform **with very little configuration**. I'm also speaking about applications in which developers need the flexibility to build, ship, and maintain code at scale.

<Aside title="Note" tag="Note">
  It's important to note that this programming concept is highly dependent on
  the needs of the application, therefore, not all applications require this
  approach. **Containerization is an approach that developers opt into as their
  application grows**.
</Aside>

To achieve this, we need some way to package/containerize an application so that when we move an application from one environment to another, the application has everything needed to successfully run/execute. There are many ways to replicate the environment that your code currently runs in but of those methods containerized environments have become very popular.

## What are containers?

Containers are packages of software that contain all of the necessary elements to run an application in any environment. In this way, containers virtualize the operating system and allow for software to run anywhere -- from a private data centre's to public cloud infrastructures.

<With_Container_ContainerDiagram />

Let's imagine that your application was the orange box above and it had dependencies that were essential for its operation -- things like a database layer, and having the correct run time environment installed. When setting up a production environment or another development environment, you have to be aware of these dependencies because if they're not set up properly then your application won't run. Think of the green box as the container that contains your application and all of its dependencies. Now when you set up a production environment or another development environment, you simply copy the green box and now you have confidence that the new environment has everything needed to successfully run your application.

Okay, this is cool and all but how is it the case that we can take a container move it to another computer and still have our application work as expected? Granted, we established that containers allow us to package all the dependencies needed to successfully run our application but how and why does it work?

We spoke a bit earlier about how virtual machines allow us to virtualize hardware, well containers have similar properties as they allow us to virtualize operating systems. From the point of view of the application running inside of a container, the container itself is seen as the operating system. Therefore, these containerized applications are unaware of the outside environment.

Here we have two different sandbox environments and you can think of these as containers for an application. Each of these sandbox environments has elements inside that can be manipulated/moved around but these elements are isolated to the container they're in, therefore, are unaware of their outside environment.

**You can drag the elements in each container around**.

<With_Container_SandboxContainer />

From the point of view of the computer, containers are just another running process on the computer. For this reason, there is now the possibility of having multiple instances of the same container running on your computer. Similar to how you can have multiple browser windows open at the same time, you can have multiple containers running at the same time and they will not interfere with one another.

Pop Quiz!
<With_Container_Quiz_1 />

Imagine that you've just launched your application and after a few days it starts to gain a lot of popularity. Your server needs to be able to handle the increased traffic, therefore it needs some way to scale your application. This can either be done 1) **vertically** by improving the compute hardware in which your application is running or 2) **horizontally** by creating multiple instances of your application. The former is most often done by using virtual machines, while the latter is done by creating new containers.

This sparks the question of how do we even begin to create a containerized application.

## What is docker?

Docker is a set of platform-as-a-service products that help deliver software in containers. It was developed by Solomon Hykes in 2013 and it has become the most popular tools when packaging applications and preparing them for another environment. Docker enables developers to pack applications into containers that run as instances of docker images thereby making it easier, and safer to build & manage applications.

The overarching dogma that streamlines the process of creating/managing containers is outlined in the diagram below.

![The process of docker](docker_process)

Developers write a **docker file** which outline the instructions on how to build **docker images**. An image is a multilayered template file used to construct **docker containers** and these images include things from application code to libraries, tools, dependencies and any other files needed to make the application run. You can think of images as a snapshot of a virtual environment at a single point in time thus images are said to be immutable. Although an image cannot be changed, it can be duplicated, shared and deleted. **Docker containers** are virtualized runtime environments used to create, run and deploy applications that are isolated from the underlying hardware. As we've talked about earlier, containers virtualize the `OS` but they also share the underlying kernel thus are very lightweight and can be created and destroyed relatively quickly.

## Building an image from a docker file

Let's try to create a docker image by writing our own docker file. Let's say that we've finished building our node server using express and we want to dockerize it before deploying it to a platform of choice.

We first need to install [Docker Desktop](https://www.docker.com), a desktop GUI that allows you to build, interact, and share your docker containers.

In the root directory of your project, create a docker file. This docker file does not have an extension and is simply named `Dockerfile`. The first line of every docker file specifies the **base image** from which the new image for your application is going to be built -- Ie/ the starting point of the image for your application. I say this with caution because you have the flexibility to start from any point; meaning that you could very well start with just the operating system.

<Aside title="The gotcha about docker" tag="Note">
  It's awesome that containers share the underlying kernel with the host machine
  as it makes containers very lightweight and speedy. However, this fact creates
  a "gotcha" in that you can only install containers that are of the same `OS`
  as your host machine. 
  
  You can only install and run a Linux container on a
  Linux machine. Conversely, you **cannot** install and run a windows container
  on a Linux machine

</Aside>

Knowing that we are trying to containerize a `node.js` `express app` if we were to go down this route (starting from just the `OS`), then our next course of action would be to install `node` inside our container.

Luckily, programmers are deliberately lazy✌️, therefore, there are public registries for popular docker images from which you can start your build. There are many public registries, but the main one is [Docker Hub](https://hub.docker.com).

So we can now start from a node image. **Notice** that I can specify the version of node that I want to use by appending a `:16` -- this is saying that we are going to be using version 16 of `node` in our image. Similarly, saying `node:12`, indicates that we wish to use version 12 of `node.js` in our image.

```docker
./Dockerfile

FROM node:16-alpine
```

By default, all files are dumbed into the root folder so to have some organization we will need to create a folder for our application code. We do this by setting the working directory -- if the directory we wish to switch to does not exist then the directory will be created. Here we are setting the working directory to `/app`.

```docker
./Dockerfile

FROM node:16-alpine

WORKDIR /app
```

We now have two options, we can

1. Copy all our source code into the container, npm install our dependencies and start our server

```docker
./Dockerfile

FROM node:16-alpine

WORKDIR /app

COPY . .

RUN npm install
```

2. Start by just copying the package JSON into the container and then installing the dependencies before copying the rest of our source code into the container

```docker
./Dockerfile

FROM node:16-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .
```

There is a difference between the two approaches and in short option 2 is the preferred method. Previously we talked about how a docker image is a multilayered template file used to construct **docker containers**.

<With_Container_DockerImgLayer />

**Multilayered** is the important term here as each command in a docker file creates a new layer. Docker attempts to cache each layer as it is going through the build and will only recompute/re-run the layer if there is a change between builds. Using **option 1** means that with every change to our source code docker is going to copy and re-install our node packages in addition to the source code. This is inefficient and leads to longer builds, therefore, we may want to opt into taking advantage of caching. This means that the docker container would only copy and re-install the dependencies when the `package.json` changes. Therefore, **option 2** would be the most ideal when writing our docker file.

Now that we've successfully installed our dependencies and copied our source code into our container, we need a way to expose a port on our container so that we can connect to our express app inside the container. Although we've told `express` to be listening on a certain port for HTTP methods, that port is currently not available outside the container. Therefore, we manually tell docker to expose a port. Additionally, by default and for security reasons, there are no exposed ports on a new container so all the more reason why we manually have to set one. We do this by using the `EXPOSE` keyword.

```docker
./Dockerfile

FROM node:16-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5001
```

We finally have to start our container using the `CMD` instruction and there can only be one of these per docker file. It tells the container how to run the application.

The `CMD` instruction is structured as an array of strings where each string is a command in the terminal. For our express app, it would look something like this

```docker
./Dockerfile

FROM node:16-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5001

CMD ["npm", "start"]
```

We now have all the instructions to completely build our docker image. We can now run the docker build command. The `-t` flag indicates that we want to tag our build so that we can make it easier to find and run our container.

```bash
docker build -t demo/express-docker-app:1.0
```

There are a ton of other flags that can be used during the build process and they can be found [here](https://docs.docker.com/engine/reference/commandline/build/).

Now that the container is built, you can either `push` it up to a container registry like dockerhub or we can `run` the container locally. We can do this by using the docker run command followed by the build id or the tag name.

```bash
docker run demo/express-docker-app:1.0
```

We also have to port forward all our requests made to the open port on our host machine to the open port on our running docker container. We do this by supplying a port binding flag `-p` in our docker run command.

```bash
docker run -p 5001:5001 demo/express-docker-app:1.0
```

The number on the left is the port on the host machine, while the number on the right is the port on the docker container. `host machine port: docker container port`.

We now have a running container!

Pop Quiz!
<With_Container_Quiz_2 />

### Volumes

It's important to note that containers are stateless, thus when a container is destroyed, any state or data inside the container will be lost. However, there may be situations where you want to store data that is created inside the container, and we can do this with **volumes**. A **volume** is just a dedicated folder that is created on the host machine, and containers can have access to this volume to read and write data.

To create a volume, we use the create volume command inside our terminal

```bash
docker volume create db-vol
```

We can then mount the volume inside a container when we run the container

```bash
docker run --mount source=db-vol,target=/db
```

## Optimizing our container

Security is a really big part of containerization and plays a key role in answering our question of what it means to containerize an application. We have to remember that we are virtualizing an operating system, therefore, like all other operating systems, and dependencies, containers are also subject to vulnerabilities. Therefore, it's important that we think about and implement measures to protect against these vulnerabilities.

Earlier, when we were creating our docker file, we were speaking about how we could add flags in our docker file to specify the version of node we wanted to use. You may have also noticed an additional flag that read `-alpine`. The `-alpine` flag specifies that we want to use the `-alpine` distribution of Linux; a much smaller Linux distro.

<Aside title="Slimming containers" tag="FYI">
	Slimming containers is the process of optimizing the size of the container to ensure that the container is built with only the essential components necessary to power the application.
  
  Using just the latest node image in our container, we are incurring an image size of ~353 MB, however, if we were to use the slim version it would be ~76 MB. Note, those are only base image sizes and do not include our application. However, using the smaller base images contributes to producing an overall smaller image for our application.

</Aside>

Using this flag creates a much smaller image for our application, but more importantly, it reduces what is known as the **attack surface** -- a summation of potential entry points for an unauthorized user to gain read/write access to our environment.

There are other ways in which you can slim down your docker images:

- Only install packages that you need
- Use multi-stage builds
- Use a `.dockerignore` file
- Take advantage of caching
- Use tools such as [dive](https://github.com/wagoodman/dive) or [Docker Slim](https://dockersl.im) to inspect your docker images and containers

## Wrapping up

Containerization is an approach that makes it easier for developers to build, ship, and maintain applications. Having said this, I think it's an approach that developers should think about and implement as the size of their application grows -- it's not something that developers should implement at the start of the application process.

We spoke earlier about how implementing containerization is application dependent, and thus concluding that not all applications need to be containerized. It may be easier to implement a one-click deployment strategy with services such as Netlify for static websites. However, in cases where there's a more involved process of creating web services and/or applications, developer's may benefit from implementing containers as it provides a ton of flexibility to the developer and/or the team.

Nonetheless, these decisions are left up to the developers or the development team to ponder!

All right, I'm going to wrap it up there! Hope you found this useful, and I'll catch you in the next one... Peace!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>programming</category>
        </item>
        <item>
            <title><![CDATA[Getting Started with Programming in 2022]]></title>
            <link>https://www.nonsoo.com/posts/getting-started-with-programming</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/getting-started-with-programming</guid>
            <pubDate>Tue, 22 Nov 2022 00:01:14 GMT</pubDate>
            <description><![CDATA[Most often we use the new year as a time to learn new skills and break bad habits and with the rapid expansion of technology into our daily lives, it would be a great idea to add programming as a skill to learn for 2022. Most often, the people near me, be it friends/co-workers are interested in learning how to program but have no clue where to start. So, today, we'll be talking about why it would be good to learn programming in 2022 and how to even get started. We'll touch on what resources are available to get started, be it wanting to learn on your own or wanting to go to a boot camp.]]></description>
            <content:encoded><![CDATA[
Most often we use the new year as a time to learn new skills and break bad habits and with the rapid expansion of technology into our daily lives, it would be a great idea to add programming as a skill to learn for 2022. Most often, the people near me, be it friends/co-workers are interested in learning how to program but have no clue where to start. So, today, we'll be talking about why it would be good to learn programming in 2022 and how to even get started. We'll touch on what resources are available to get started, be it wanting to learn on your own or wanting to go to a boot camp.

## Why even learn to Program?

Programming is a skill that has the potential to unlock even more important life skills such as problem-solving and persistence. Problem-solving, I find this skill very fascinating because it's a type of skill that is not directly taught but yet somehow acquired. I think it's a skill that's learned through examples and many hours of practice. Seeing how others work through a problem, especially programming problems can be very helpful and it may give you new insights into how you can incorporate their ideas into a problem that you are trying to solve.

Programming also teaches you persistence -- you may find that when working on your next idea, solutions to some problems may be very apparat while solutions to other problems may take a bit more time to surface. The mere fact that you know you can use programming to bring your idea to life may be all that's needed to stay determined to pass the roadblock that is in front of you.

The penultimate reason why you would want to learn to program, the skill provides you with an avenue for a career change as year after year the demand for programming jobs grows rapidly. Companies are adapting to new technological changes and seeking programmers to aid in their ushering into a new era.

Finally, Programming combines creativity with technical skills. You gain the ability to create whatever you want! Be it an app, that lets you book your trip to your dream destination or a website that allows you to order take out -- you are only limited by what you can imagine!

## What programming languages do I start with?

This is the question that plagues many people that are getting started with programming -- there are just so many languages to choose from! From personal experience, I find that most individuals gripe with programming and I guess a fair misconception is that you cannot directly see the impact of what you are coding. I say this is a fair misconception as I can understand that it may be lost in translation how solving coding problems/challenges leads you to develop an application or a website. So most often I say that people should start with languages where you can visually see what you're coding as I think that would be a better way and would keep you more motivated. Visually see in the sense that typing out "I want this button to be red" should allow you to see a button turn red.

In the programming world, this type of programming is known as the front-end, the creation and development of user interfaces. How is the application going to be structured? How big are the buttons going to be? How does typography play into the useability of the application I'm building? Everything that encompasses the style and function of an application falls under the umbrella that is the front end.

### Web Development

Web development is concerned with developing either applications for the web or websites. The structure for the front end of any website is made up of three main languages: HTML, CSS, and JavaScript.

**HyperText Markup Language, better known as HTML** is the backbone of any website as it's the language that is responsible for the content and what is displayed on the website.

Below is a block of _HTML_ code that when run will show Hello There in your browser:

```html
<html>
  <body>
    <p class="firstPara">Hello There</p>
    <p class="secP">This is the second Paragraph</p>
  </body>
</html>
```

**Cascading Style Sheet, better known as CSS** is responsible for all the styling of a website as it's used to answer questions like: How big do I make this button? What colour should it be? What about spacing, layout, and typography? The very cool thing is that modern CSS can be used to answer even more complex questions -- would some users of my application prefer a dark theme or even reduced motion?

Below is a block of _CSS_ code that selects the second paragraph and makes the text larger:

```css
.secP {
  font-size: 50px;
}
```

**JavaScript** is responsible for the functionality of a website as it is concerned with a question like What happens when I click this button? Let's take an add-to-cart button on your favourite e-commerce website for example -- to the end-user pressing that button may seem like it is just navigating you to the shopping cart so that you can complete your purchase, however, they're more going on behind the scenes. The button is also responsible for making a request to an external set of computers, _a server_, to add the appropriate item to the cart for this specific user. Only once that is complete, will you be navigated to the shopping cart for you to check out.

Below is an example of _JavaScript_ code that will print Hello there when run:

```js
console.log("Hello There");
```

These may seem very daunting to get started with but the above three languages are very beginner-friendly and have a ton of online resources to help you get started.

### Mobile Development

The other type of development that has a front-end aspect to it is mobile development as this is concerned with making applications for mobile devices, be it IOS or Android devices.

The languages used here are dependent on the platform you are trying to develop for:

**IOS** development moved to the _Swift_ programming language a while back and is very beginner-friendly with a lot of resources available.

**Android** development moved to the _Kotlin_ programming language a while back and has also been found to be very beginner-friendly with a lot of resources available.

### For Learning concepts

**Python** will always be a staple language to learn as it is very easy to learn with its easy-to-read syntax which allows you to focus on learning the concepts. Below is a block of _python_ code that when run will say Hello There.

```py
print("Hello There")
```

## What resources are available?

There are numerous resources available at your disposal when it comes to learning to code and it doesn't matter which language you start with, the resources are available. All the resources that I'm listing below are **ABSOLUTELY FREE**!

I always recommend **Free Code Camp** as the best place to start as they have instructional videos that break down fundamental concepts and coding challenges to help you practice your understanding of those concepts.

For Web development, **The Odin Project** and **Frontend Mentor** are very good resources. _The Odin Project_ will teach you web development step by step while you also build out a website with their code along with instructions while _Frontend Mentor_ gives you frontend challenges for you to solve. Most of the challenges include providing you with a layout of a website, most often as a JPG, for you to recreate using HTML, CSS, and sometimes JavaScript.

But by far, YouTube is one of the best resources available to learn programming with numerous YouTube channels providing excellent instruction and tips!

Dev Ed, Ania Kubow, Fireship, and Programming with Mosh are a few of my favourite channels to watch on YouTube.

And of course my channel, [Linked Here](https://www.youtube.com/channel/UCX5U1Acli00LRTV3FijGL1g).

## Conclusion

Now that this is complete, I hope I've encouraged you to give programming a try! I can't wait to see what you create!

Check out [the Youtube Channel](https://www.youtube.com/channel/UCX5U1Acli00LRTV3FijGL1g) for tips/tricks and tutorials on programming!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>Programming</category>
        </item>
        <item>
            <title><![CDATA[State Management in React]]></title>
            <link>https://www.nonsoo.com/posts/state-management-in-react</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/state-management-in-react</guid>
            <pubDate>Tue, 22 Nov 2022 00:01:14 GMT</pubDate>
            <description><![CDATA[Properly managing state within a react application can greatly improve the developer experience and accessibility to information needed by specific components. In this article we'll explore why and how to properly manage state within a react application.]]></description>
            <content:encoded><![CDATA[
What is it? Why should I care about it? and how do I properly manage state within my app?

Okay, we'll get to all of that but lefts first talk about state.

## What is state?

> **State is just data that changes over time.**

In the case of front ends, we can make our application or UI react to these changes so that we can use something like conditional rendering to show or hide a certain feature.

For example, think of a modal; A modal has two options or two states. A modal can either be opened or closed. Knowing the state of that modal allows us to use conditional rendering to either show or hide the modal using CSS.

An even more complicated example is knowing when a user has logged into your application. There are a lot of different authentication workflows but ultimately it boils down to getting this user object from your backend API, finding a way to store the state so that you can persist it through the application for other components to have knowledge of whether a user is logged in. Knowing when a user is logged into our application is crucial because it allows us to only show features of our application to registered and logged-in users. It further allows us to know if a user has paid to see a specific kind of information.

## Why should state be properly managed?

Okay okay, knowing what the definition of state and what it allows us to do is cool but why should I as a developer care about how it's managed? It's not like the end user may even notice a difference. Properly managing state within your application leads to:

1. A better developer experience
2. Makes it easier to access information when it is needed by a specific component

If you've been working with react for a while, you'll recall that one of the first concepts you learn is props. So you might be wondering, can't we just pass information through props to the components that need it? I mean yes you can do that and it is a very viable option but it leads to something known as prop drilling.

> **Prop drilling is when information is passed from a parent component to the 4,5,6th grand-child component. Some of the components may not even need the information but serve as passageways to get information to the grand-child component**

Prop drilling can lead to a very poor developer experience, especially when working on large projects. You might be wondering if there are any other ways to manage state within an application?

## How do I properly manage state?

There are various state management libraries that allow you to properly manage state within your application. These libraries include:

- Context API
- Redux & Redux Toolkit
- Recoil
- A lot of other libraries exist as well

There are a lot of other libraries that exist as well but the cool thing is that these libraries allow you to decouple your data from the components. So instead of having the component responsible for storing the data/state, the data can be stored in a separate store that is not attached to a specific component.

> The above is the case with Redux -- the context API requires that you store state in a specific component and then any child of that component will have access to the store.

Any component that needs assess to the data can go to the store, retrieve the information, and then display it in the UI. Any time the information changes, it will be updated in the store, which is then reflected in the UI.

The question then becomes when do I store state locally (state defined within the component) and when do I store state globally (state that is often stored within a separate store)?

To answer this question, I ask another question: Do multiple components need access to this data?

- If Yes, then we should consider creating a global store for our data thereby allowing multiple components to have access to the data without worrying about prop drilling
- If No, then we can store the data locally -> Store the data within state inside the component

Going back to our scenario of knowing when a user is logged in -- this is a piece of state that multiple components will need to assess so it would make more sense to store this data globally to limit prop drilling. Whereas with the modal example, it would make more sense to store that state within the component unless there is some other feature that requires knowledge of the state of the modal.

## Conclusion

We've just looked at state management as a whole and why it is important to manage state within your application.

Hope you found this useful, don't forget to smash the like button and I'll catch you in the next one... Peace
]]></content:encoded>
            <author>Nonsoo</author>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[LetsCreate: React Counter Component]]></title>
            <link>https://www.nonsoo.com/posts/react-counter-component</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/react-counter-component</guid>
            <pubDate>Tue, 22 Nov 2022 00:01:14 GMT</pubDate>
            <description><![CDATA[When I started with React, the first thing I thought was ughh yet another framework to learn but honestly after using it for the past couple of years, React has really grown on me. It fun to work with  but there is always that question someone has when getting started -- Where do I even begin? This article will be exploring the basics of react, react hooks, and we will walk through how to create your first react application.]]></description>
            <content:encoded><![CDATA[
<CounterComp />

React, a JavaScript framework developed by Meta in 2013 and it's used to build user interfaces for front-end web development. It has become one of the most popular frameworks alongside Vue, Angular, svelte and a lot more.

When I started with React, the first thing I thought was ughh yet another framework to learn but honestly after using it for the past couple of years, **React** has really grown on me. There are a lot of new things that have come into place over the years and I think it has really improved the developer experience. It honestly fun to work with React but there is always that question someone has when getting started -- **where do I even begin?**

This article assumes that you know the basics of `JavaScript` and so we will not be defining concepts such as variables, functions, arrays, objects, and objects. We will however be exploring the basics of **react** and walking through how to create your first **react** application. We're going to be building a counter application which will allow users to:

1. see the current count
2. increment the count
3. decrement the count
4. reset the count to 0.

I think React gaining populartity because its written in `JSX`, a language that combines `HTML` and `JavaScript`. `jsx` allows us to write and inject `javascript` code into our `HTML` thereby abstracting away function calls like `.createElement`. I say this as `JSX` looks very similar to `HTML`, however, these two languages are not the same.

## Creating the app

Before we get started with creating our react app, you are going to need Node.JS installed on your computer. If you haven't done so already you can head over to the [Node JS](https://nodejs.org/en/) website and install the latest version of node. Once this is complete you can check the current version of node installed on your computer by running

```bash
node -v
```

We need to initialize our application in the working directory. This can be anywhere but for starters we are going to be on the desktop. React applications can be initizeled in many different ways, but here we're going to be sticking with the basic client-side rendered application. In your command line/ terminal run the following command:

```bash
npx i create-react-app counter-app
```

Running this command will reach out to all the services needed to install the components to required to run a react app and packages inside a folder called **counter—app** that will be placed in your desktop.

There are a few files that I want to bring your attendtion to:

1. The `./package.json` file stores all the information required to properly install your application on another computer. Information such as the requried dependancies (code/modules that the application you're about to build depends on), the scripts for your application, and a bunch of other information.
2. `./public` folder contains all the public assets for your application. Assets such as imgs, favicons, and the `index.html` file.
3. There are also some other boiler plate code such as test files -- files ending in `.test.js`. It is a good idea to run tests on your application but for the purposes of this demo we are not going to be doing so. Therefore, we are going to remove files like the test files, the index.css (has styles for what you currently see in the web browser → we are going to be creating our own styles in the app.css file). Also remove the SVG file and any reference to it inside the project. The code the the `app.js` file show now look like the following:

```jsx
import react from "react";
const app = () => {
  return <div></div>;
};
```

We are first going to create something for use to view the current counter. Use a paragraph tag and at first we are going to set the to a static value, 0. We are doing this so we can visualize where everything is on the screen — we will later change it to dynamic value. We also need some buttons that will allow us to increment, decrement, and reset the count.

```jsx
import react from "react";
const app = () => {
  return (
    <div>
      <p>0</p>
      <button>Increment</button>
      <button>Decrement</button>
      <button>Reset</button>
    </div>
  );
};
```

Doing this just puts the buttons on the screen, however, we need a way to actually increment, decrement and reset the count. To do this we are going to create functions that will handle that logic and then we will call those functions when the respective buttons are pressed. In react, the button element(any element for that matter) takes on a onClick event that can the triggered when the element is clicked. **onClick** takes in a callback function to prevent it from being triggered when the component mounts — the callback function will call the respective functions for the buttons. Add onClick to the buttons and then reference the respective function → we still have to create these functions. Add the following:

```jsx
import react from "react";
const app = () => {
  return (
    <div>
      <p>0</p>
      <button onClick={() => Increment()}>Increment</button>
      <button onClick={() => Decrement()}>Decrement</button>
      <button onClick={() => Reset()}>Reset</button>
    </div>
  );
};
export default app;
```

Let's think about this, we want to have a value in our app that changes in response to an action. This dynamic value is called state and we first have import the hook that allows us to store & update state. React hooks are very convinient functions that abstract away a lot logic which make our lives (developers) easier when writting an application. It was introduced just after react switched from being written with class components to function components.

> Some common `react hooks` that you will encouter are useState, useEffect, useCallback, useMemo, useRef, and more. You also have the flexibility of writting your own.

We are going to be importing the `useState` hook from react and then using it in our application. When importing things from the same library we can write them in one line and have it separated by a comma. We do this by adding the following:

```jsx
import react, { useState } from "react";
```

The useState hook returns an array with two values inside; the first value in the array is our actual state variable while the second value is a function we can use to set that state. These name can be set to anything, however, by convention we set the variable names equal to what they are going to refer to in our app → like any other variable name.

```jsx
const [count, setCount] = useState(0);
```

By passing a value into the useState we can set the default value for that state. Above we are setting the default value to 0.

We are going to create the `increment`, `decrement`, and `reset` function which is going to be responsible for incrementing, decrementing, and resetting our counter. The increment function will look something like this:

```jsx
const Increment = () => {
  setCount(count + 1);
};
```

Inside the increment function, we are calling the `setCount` function from our `useState` hook and passing in `count + 1`. This is saying that everytime the `Increment` function is called, we are going to increment the the current count by 1.

While the above code snippet works to update the state of the count, I should also acknowledge that there another way to update the state. You will most often see state updates written using this method the new state relies on the previous state. The following is an example of what I mean:

```jsx
const Increment = () => {
  setCount((prev) => prev + 1);
};
```

This has to do with the way `react` updates state. If we were to call `setCount(count+1)` 2X inside the increment function, you would notice that it doesn't work as expected. You would likely find that you are only incrementing the count by 1 instead of 2. React batches state updates together, and runs them at the same time. Therefore, the count is not updated and is using the initial value. The demo below to illustrate what I mean when this increment function is called:

```jsx
const Increment = () => {
  setCount(count + 1);
  setCount(count + 1);
};
```

<CounterCompBroken />

We are going to do the following for the `Decrement` and `Reset` function, so you should end up with something like this:

```jsx
const Increment = () => {
  setCount((prev) => prev + 1);
};

const Decrement = () => {
  setCount((prev) => prev - 1);
};

const Reset = () => {
  setCount(0);
};
```

All we have to do now is replace the static value inside the paragraph tag with the dynamic state variable -- `Count`.

```html
--
<p>0</p>
++
<p>{count}</p>
```

If everything worked out, you should now have a counter application that has the same functionallity as the one below.

<CounterComp />

## Congragulations!

We've made it and we've just completed our first `React` Application!! Yay! We explored the basics of `react`, described the similarities/differences between `JSX` & `HTML`, explored how to get setup with `react`, and explored the `react hook` useState.
]]></content:encoded>
            <author>Nonsoo</author>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[From a list to one number]]></title>
            <link>https://www.nonsoo.com/posts/javascript-reduce-method</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/javascript-reduce-method</guid>
            <pubDate>Tue, 22 Nov 2022 00:01:14 GMT</pubDate>
            <description><![CDATA[Summations over an iterable can be accoumplished in numberous ways, however, the array methods in javascript provide a high order function that make doing these operation easier. In this article, we'll explore the reduce method in javascript and how we can use it to turn a list of numbers into one number.]]></description>
            <content:encoded><![CDATA[
## Introduction

The JavaScript reduce method is one of the higher order functions introduced in es6 which allows us to "reduce" the values inside of an array into a single value. Today, we will be taking a look at how to implement this in our code.

## Getting Started

The `.reduce()` method is a higher order function that can be called on any array -- see below:

```js
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.reduce();
```

Like all the other array methods `.reduce()` loops through your entire array. The difference here is that `.reduce()` is a function has two parameters, one being a function while the other is the initial value of what we call and accumulator -- this is the thing that will increment at every iteration of the loop.

```js
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.reduce(() => {}, 0);
```

The function inside reduce, takes in two parameters itself, one being an accumulator while the other being the value of the current position in the array. See Below:

```js
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.reduce((acc, curr) => {}, 0);
```

To update the accumulator at each iteration we must add a return it inside the function. We can assign this function to a variable which can then be used for anything.

## Using Reduce: Example

Lets say we have an array from 1 - 10 and we need to add all the elements in the array to determine the total, we can use the reduce method to accomplish this -- We can call the reduce method on our array, setup the accumulator and current parameters and also pass in an initial value of 0.

```js
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.reduce((acc, curr) => {
  return acc + cur;
}, 0);
```

## Using reduce: Another Example

Going over out class object that we created (link to other post), lets say we wamted to calculate the average for the class. We can either write a while loop or for loop to accomplish this or we can use the reduce method.

Here is an array of objects where each object represents a student in the class.

```js
const students = [
  {
    Name: "John",
    Grade: 90,
  },
  {
    Name: "Sarah",
    Grade: 95,
  },
  {
    Name: "Jane",
    Grade: 80,
  },
  {
    Name: "Julie",
    Grade: 79,
  },
];
```

Using the reduce method:

```js
const students = [
  {
    Name: "John",
    Grade: 90,
  },
  {
    Name: "Sarah",
    Grade: 95,
  },
  {
    Name: "Jane",
    Grade: 80,
  },
  {
    Name: "Julie",
    Grade: 79,
  },
];

const TotalMarks = students.reduce((acc, curr) => acc + cur, 0);
const averageMark = TotalMakrs / students.length;
console.log(averageMark);
```

Now that this is complete, we have a way to reduce an array into a single value without writing our own loop!

## Question for you

Now knowing this, here's a question for you -- how else can we implement the reduce method?

---

Check out the youtube channel to see how we are implementing the feature in the app we are building! [theYoutubeChannel](https://www.youtube.com/channel/UCX5U1Acli00LRTV3FijGL1g)
]]></content:encoded>
            <author>Nonsoo</author>
            <category>Javascript</category>
        </item>
        <item>
            <title><![CDATA[How can we automate a simple task to make our lives easier?]]></title>
            <link>https://www.nonsoo.com/posts/create-uuid-generator</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/create-uuid-generator</guid>
            <pubDate>Tue, 22 Nov 2022 00:01:13 GMT</pubDate>
            <description><![CDATA[So you need to sign up participants to this game that your team is building and you realize that you need some way to identify each participant other than their name because for the obvious reason there are multiple participants that may have the same name. Your project manager has suggested that you use a unique identifier for each participant but has insisted that this identifier be of an alphanumeric value. In this article, we'll explore how to create a UUID generator to get a text file on our desktop that is populated the number of unique identifiers that asked for.]]></description>
            <content:encoded><![CDATA[
## Introduction

Let's suppose you are given the tedious task of making a unique identifier for each student in a class of 500 and for security purposes you are told these IDs have to be alphanumeric. You're thinking to yourself, how did I end up having the task assigned to me? Relentlessly shrugging your shoulders, you remember that you're a programmer and that you could just code your way out of this problem! Today we'll be walking through how to make a UUID generator whereby when you run the program you get a text file on your desktop that is populated with the number of UUIDs you asked for.

## Getting Started

You might be thinking, now I have to figure out how to make a random alphanumeric character generator that I can use in the rest of my program. You could go down that route, writing a function that is responsible for generating this random alphanumeric character of n length and all that jazz. However, programmers are also lazy and there's no need to re-write this function that is publicly available for you to use which generates these IDs. We are going to be doing this using python but this can be done in other languages as well like JavaScript, PHP, Java, etc.

## Create a unique ID

There's a UUID module in python that we can import and it gives us access to versions 1,3,4, and 5 of the UUID generator. We can then specify the version of the UUID generator we want to use and store it in a variable.

```py
import uuid

myUUID = uuid.uuid4()
```

This returns an instance of a Python UUID class so we need to convert it to a string to view the generated UUID. Below is a code block that converts the class instance to a string and prints out the result.

```py
import uuid

myUUID = uuid.uuid4()

print("The generated uuid is: " + str(myUUID))
```

## Creating our program

We want a function whereby we can pass in a number and generate a list of unique IDs where the length of the list is equal to the number that was passed in.

Below is a block of code that defines the function.

```py
import uuid

def UUIDgen(num):
    """
        A function that takes in a number and returns a list of UUIDs
        where the length of the list is equal to the function that
        is passed in.
    """
    pass

if __name__=="__main__":
    pass

```

We first need to create the list that is going to hold the UUIDs and then we can set up a loop that adds the newly generated UUID to the list. This loop would continue until it gets to the number that was passed in. Below is the block of code that shows this:

```py
import uuid

def UUIDgen(num):
    """
        A function that takes in a number and returns a list of UUIDs
        where the length of the list is equal to the function that
        is passed in.
    """
    lstUUID = []
    count = 0

    while count < num:
        lstUUID.append(str(uuid.uuid4()))
        count = count + 1
    return lstUUID

if __name__=="__main__":
    pass

```

> **Don't forget that the uuid4 returns a class instance and thus we need to convert it to a string before appending it to the list**

For the program, we can ask the user how many UUIDs they want to be generated and store their response in a variable. We can do this by writing `lenLst = input("How many UUIDs do you want to be generated?: ")`

We can then use our function to generate that list of UUID.

> **Remember that input() stores responses in a string so before we use it we need to convert the lenLst variable to an int**

```py
import uuid

def UUIDgen(num):
    """
        A function that takes in a number and returns a list of UUIDs
        where the length of the list is equal to the function that
        is passed in.
    """
    lstUUID = []
    count = 0

    while count < num:
        lstUUID.append(str(uuid.uuid4()))
        count = count + 1
    return lstUUID

if __name__=="__main__":
    lenLst = input("How many UUIDs do you want generated?: ")

    genUUIDLst = UUIDgen(int(lenLst))

```

genUUIDLst now holds a list of UUIDs where the list is of length n. We now have to write the items of this list to a text file and we're done.

We can open a new file in write mode by using the `open()` function and then loop throughout `genUUIDLst` and write each item to the file. We do this doing the following:

```py
if __name__=="__main__":
    lenLst = input("How many UUIDs do you want generated?: ")

    genUUIDLst = UUIDgen(int(lenLst))

    with open("./UUID_Lst.txt","w") as new_file:
        for i in range(len(genUUIDLst)):
            new_file.write("{}. {} \n \n".format(i+1,genUUIDLst[i]))


```

After writing all the information to the file, we need to close the file and then we can print a state to know when this has finished executing.

The final code block should look something like this:

```py
import uuid

def UUIDgen(num):
    """
        A function that takes in a number and returns a list of UUIDs
        where the length of the list is equal to the function that
        is passed in.
    """
    lstUUID = []
    count = 0

    while count < num:
        lstUUID.append(str(uuid.uuid4()))
        count = count + 1
    return lstUUID

if __name__=="__main__":
    lenLst = input("How many UUIDs do you want generated?: ")

    genUUIDLst = UUIDgen(int(lenLst))

    with open("./UUID_Lst.txt","w") as new_file:
        for i in range(len(genUUIDLst)):
            new_file.write("{}. {} \n \n".format(i+1,genUUIDLst[i]))
    print("Done!")
```

**We are DONE!**

## Conclusion

Now that this is complete, we have a way to generate a list of UUIDs and save them to a file on our desktop! Question for you, What else can you do with this UUID generator?

Check out [the Youtube Channel](https://www.youtube.com/channel/UCX5U1Acli00LRTV3FijGL1g) for tips/tricks and tutorials on programming!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>python</category>
        </item>
        <item>
            <title><![CDATA[How can we create a real-time search filter on the client side?]]></title>
            <link>https://www.nonsoo.com/posts/javascript-filter-method</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/javascript-filter-method</guid>
            <pubDate>Tue, 22 Nov 2022 00:01:13 GMT</pubDate>
            <description><![CDATA[We're going to be using some javascript to simulate a real-time search feature in an application. The filter method which can be used on any iterable provides us a way create the search feature. Today, we are going to be exploring the javascript filter method and its use cases.]]></description>
            <content:encoded><![CDATA[
## Introduction

The JavaScript filter method is one of the higher-order functions that allows us to filter content based on a condition that has been set. Today, we will take a look at how to implement it in our code as well as look at some "Real-World examples" of how it could be used as means to search through an array of content.

## Getting Started

The `.filter()` method is a higher-order function that can be called on any array or object -- see below:

```js
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.filter();
```

It takes in a function as its argument and also has a return value which is an array that contains the elements that pass the condition implemented. The filter method essentially loops through every item in the array that it is called on and checks the current iteration on a parameter that is set. Like state previously, if the condition is met, then the added to the array that is returned by the function. The example below shows us using the filter method to remove the number 4 from the array called "arr".

```js
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.filter((number) => number != 4);
```

The return value here will be `[1,2,3,5,6,7,8,9,10]`

### Example 2

For another example, more interesting -- Given an array of objects, where each object represents a student that has taken a test, return the names of the students that scored at least an 80% on the test. We can use the array filter method to do this. The object contains two keys -- the student's name and their grade `{Name:"", Grade:0}`.

```js
const students = [
  {
    Name: "John",
    Grade: 90,
  },
  {
    Name: "Sarah",
    Grade: 95,
  },
  {
    Name: "Jane",
    Grade: 80,
  },
  {
    Name: "Julie",
    Grade: 79,
  },
];
```

Since we are given an array of objects, we can use the filter method to loop through the entire array and check if the current student's grade is greater or equal to 80%. It looks something like this:

```js
const students = [
  {
    Name: "John",
    Grade: 90,
  },
  {
    Name: "Sarah",
    Grade: 95,
  },
  {
    Name: "Jane",
    Grade: 80,
  },
  {
    Name: "Julie",
    Grade: 79,
  },
];

students.filter((student) => {
  if (student.Grade >= 80) {
    return student.Name;
  }
});
```

A shorthand for this would be that we can store the return value in a variable so that we can use it later. The following look something like this:

```js
const students = [
  {
    Name: "John",
    Grade: 90,
  },
  {
    Name: "Sarah",
    Grade: 95,
  },
  {
    Name: "Jane",
    Grade: 80,
  },
  {
    Name: "Julie",
    Grade: 79,
  },
];

const stuAbove80 = students.filter((student) => student.Grade >= 80);
```

---

## The Fun Stuff -- Add a search field to your web application

A common feature in most applications that have large amounts of scrollable content is a search field -- users enjoy the experience of being able to quickly search for the content they want to find since it saves them time in the end. This feature can be accomplished in many ways but today we will be using the javascript filter method to add a search feature to the student's array we have been working with, this time we will be searching for a specific student by name. The advantage of using the filter method is that we can filter out the content as the user types -- this is best described when you are searching for something to watch on Netflix.

You can do this with vanilla JavaScript, however, today we will be using a library such as react to create our UI.

**Let's pretend that we made an API request and this is the data you got back:**

```js
const students = [
  {
    Name: "John",
    Grade: 90,
  },
  {
    Name: "Sarah",
    Grade: 95,
  },
  {
    Name: "Jane",
    Grade: 80,
  },
  {
    Name: "Julie",
    Grade: 79,
  },
];
```

We are storing it in a variable called `students` so we can use it later on. Here is just some boiler code to get all the boring stuff out of the way. This just has an input field that is connected to a state variable and a component that is showing all the student names with their associated grades.

```jsx
import react from "react";

const App = () => {
  import { useState } from "react";
  const students = [
    {
      Name: "John",
      Grade: 90,
    },
    {
      Name: "Sarah",
      Grade: 95,
    },
    {
      Name: "Jane",
      Grade: 80,
    },
    {
      Name: "Julie",
      Grade: 79,
    },
  ];

  const [searchTerm, setSearchTerm] = useState("");
  return (
    <div>
      <input
        type="text"
        onChange={(e) => setSearchTerm(e.target.value)}
        defaultValue={searchTerm}
      />

      {students.map((student) => (
        <p>
          students Name:{student.Name} and their grade: {student.Grade}
        </p>
      ))}
    </div>
  );
  export default App;
};
```

To add the search feature, we can filter through the student's array and return a list of student objects with names that match the search term.

```jsx
students.filter((student) => {
  if (searchTerm == "") {
    return student;
  } else if (student.Name.toLower().includes(searchTerm.toLower())) {
    return student;
  }
  return null;
});
```

When the search bar is empty, we want to display every object in the data holder variable so we can just return every member without filtering.
Now it may seem counter-intuitive but to computers "A" is not the same as "a". To that same extent "John" is not the same a "john". So that we don't run into this issue we are going to convert the search term and the Name to lowercase and then check if the search term includes the Name.
If it does then the current student object is going to get added to the list.

We can then map through this array that is returned from the filter to display the student's name and grade using the component we created. The final code should look something like below:

```jsx
import react from "react";

const App = () => {
  import { useState } from "react";
  const students = [
    {
      Name: "John",
      Grade: 90,
    },
    {
      Name: "Sarah",
      Grade: 95,
    },
    {
      Name: "Jane",
      Grade: 80,
    },
    {
      Name: "Julie",
      Grade: 79,
    },
  ];

  const [searchTerm, setSearchTerm] = useState("");
  return (
    <div>
      <input
        type="text"
        onChange={(e) => setSearchTerm(e.target.value)}
        defaultValue={searchTerm}
      />

      {students
        .filter((student) => {
          if (searchTerm == "") {
            return student;
          } else if (student.Name.toLower().includes(searchTerm.toLower())) {
            return student;
          }
          return null;
        })
        .map((student) => (
          <p>
            students Name:{student.Name} and their grade: {student.Grade}
          </p>
        ))}
    </div>
  );
  export default App;
};
```

Now that this is complete, we have a way to search for a student by looking up a Name using a javascript function that we created!

## Question for you

Now knowing this, here's a question for you -- how else can we implement the filter method?
]]></content:encoded>
            <author>Nonsoo</author>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[How does an app know to change the appearance of a button once it's pressed?]]></title>
            <link>https://www.nonsoo.com/posts/conditional-rendering</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/conditional-rendering</guid>
            <pubDate>Mon, 21 Nov 2022 23:02:09 GMT</pubDate>
            <description><![CDATA[You've just stumbled across the about page of this blog and realized that you have an option of reading either a short or long version of the description. You start to wonder how a feature like this can be created. In short, it's all based on conditional rendering. In this article, we will explore the topic of conditional rendering and how we can use it to create custom experiences based on user input.]]></description>
            <content:encoded><![CDATA[
How does an app know to show a dashboard when I'm logged in? Better yet, how does an app know to change the appearance of a button once it has been clicked? These questions are best answered with a topic known as conditional rendering -- If this is true, then show that. The button below responds to user input as it changes colour when it's clicked. Initially, it starts as a gray colour button but then changes into a dark green button once it's pressed.

<ConditionalDemo1 />

We'll be exploring the topic of conditional rendering and how we can use it to dynamically switch components within an application based on a true or false value. We're going to walk through some code examples and some interactive demo's as well. These code examples and demo's will be mainly in **jsx/react** but conditional rendering is a topic that exists in almost any programming language.

Let's have you click the button below to see another example of conditional rendering in action. We can see that pressing the button will change the appearance; more specifically the button goes from a circle shape to a square shape. This can be done multiple times and we will be exploring how you can achieve something like this within an application that you are building.

<ConditionalDemo2 />

## How does conditional rendering work?

Conditional rendering works on boolean principles meaning that if a certain condition is satisfied, then we are going to render a specific component. Conversely, if that condition is not satisfied, then a different component will be rendered -- its all one big `if statement`. As I alluded to above, conditional rendering can be done in almost any programming language but we are going to be looking at how to implement it in javascript and then JSX. The following is a Javascript implementation:

```js
//Example 1

if (btnClicked == true) {
  btnColour = "blue";
} else {
  btnColour = "red";
}

// Example 2

const btnColour = btnClick ? "blue" : "red";

// Example 3

const btnColour2 = btnClick && "blue";
```

We can see that if the `btnClicked` variable is `true` then we are going to assign the `btnColour` a value of `"blue"` otherwise, `btnColour` gets assigned a value of `"red"`. The other ways that we can describe this logical statement is by using a Ternary operator **(example 2)** or with short circuits **(example 3)** which are also shown above.

> Ternary operator is a one-line if statement that is which is identified by a `?` and `:`. The item to the left of the question mark is what is being tested for a truthy or falsy value while the items to the right of the question mark are the return values which are separated by a colon. The item on the left of the colon will occur if the condition is true while the return value on the right will occur if the condition is false. `truthy values here : falsy values here`.
>
> The short circuit `&&` operator evaluates conditions on the left and right hand of the `&&`. This operator reads from left to right, therefore, conditions have to progressively evaluate to`true` for the overall statement to be `true`. In the case of **Example 3**, `blue` will always evaluate as `true`, therefore, if `btnClick` is `true` then `btnColour2` will be assigned `blue`.

Since conditional rendering is all one big if statement, we as the developer get a choice as to how it's implemented. We can either choose to implement a block statement or we can implement an inline statement but the result remains the same. It is a writing preference, however, you will most often find that conditional rendering is written as a ternary expression as it is after all based on a true or false value -- it's easier to read.

### Demo 1 & 2 explanation

In the first demo, you were able to click a button and watch the colours of the button change while in the second demo, you were able to click a button and watch as the shape of the button morphed from a circle to a square. Looking at these two examples, we are using conditional rendering to change the presence of a `css` class which then allows us to toggle the button between two different colours or two different shapes.

### Pagination example

Most often, when you complete a form online, you find that related information is grouped. Brands do this to limit the fatigue that completing a form brings about and it further improves the user experience. The form pagination demo above is an example of this experience and it is using conditional rendering to determine which page of the form to show.

```jsx
import { useState } from "react";

const app = () => {
  const [page, setPage] = useState(1);

  const onNextPage = () => {
    setPage((prev) => prev + 1);
  };

  return (
    <form>
      {page === 1 && <p>Content for page 1</p>}

      {page === 2 && <p>Content for page 2</p>}

      {page === 3 && <p>Content for page 3</p>}

      <button onClick={onNextPage}> Go to next Page </button>
    </form>
  );
};
```

Here we are grouping information in a form to make it easier for the user to experience our form. Based on what page the user selected, will dictate what information the user is shown. In this case, we are using short circuits `&&` to do conditional rendering. The page that will be shown is reliant on the `page` state as the components to the right of `&&` will always resolve to `true`. To further illustrate this, below is a demo of the code being shown above.

<ConditionalDemo3 />

## What else can we do with conditional rendering?

Numerous things can be accomplished with conditional rendering. Things such as:

- Showing an achievement trophy in a game/app based on whether the user earned the award

- Showing a specific module based on if the user purchased it on your course platform

- Showing login states & pagination of forms

To further illustrate this further, conditional rendering is being used on this blog website with the quiz components of this [article](https://www.nonsoo.com/posts/the-has-selector). Here, I'm keeping track of if a user has answered the question correctly and depending on this outcome I am showing a different UI to the user. It's also heavily present in the article that you're reading (above).

## To wrap up

Conditional rendering is a powerful tool that can be used to shape how you want users to experience your application. It is left up to you, the developer, to decide when and how you want to show your user's information in the application.

Hope you found this useful, don't forget to smash the like button and I'll catch you in the next one... Peace!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>programming</category>
        </item>
        <item>
            <title><![CDATA[React Router V6]]></title>
            <link>https://www.nonsoo.com/posts/react-router-guide</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/react-router-guide</guid>
            <pubDate>Mon, 21 Nov 2022 22:25:34 GMT</pubDate>
            <description><![CDATA[You may be familiar with websites having multiple pages which are interconnected and allows users to navigate to different areas of your website. Naturally, when we want to add a new page to our website, we can just create a new HTML file and link it to other pages using the anchor tag ( `<a></a>`). Additionally, other pages can then link page to this newly created page with the same anchor tag. This doesn't quite work the same when we are using something like react as react results in a single page application (SPA) -- an application that only has one HTML file. So the question then becomes how do we simulate a multiple-page experience within a SPA? ]]></description>
            <content:encoded><![CDATA[
You may be familiar with websites having multiple pages which are interconnected and allows users to navigate to different areas of your website. Naturally, when we want to add a new page to our website, we can just create a new HTML file and link it to other pages using the anchor tag ( `<a></a>`). Additionally, other pages can then link page to this newly created page with the same anchor tag.

This doesn't quite work the same when we are using something like react as react results in a single page application (SPA) -- an application that only has one HTML file. So the question then becomes how do we simulate a multiple-page experience within a SPA?

We'll be exploring the answer to this question in today's blog and seeing how we can accomplish something like this using a routing library such as react-router.

## How do we get react-router working?

To install react-router, we want to install the package `react-router-dom` using npm or yarn. Here we are going to be using npm:

```bash
npm install react-router-dom
```

### Getting Setup: The Basics

Now that this is installed we need to configure our application so that it's ready to properly handle routing. In our `index.js` file we want to import `BrowserRouter` from `react-router-dom`. We want to import this as `router` and wrap it with this component. This is being done so that all the components that are a child of App will have the ability to trigger a route change. Your `index.js` file should look something like this:

```jsx

import {BrowserRouter as Router} from "react-router-dom";
import ReactDom from "react-dom";
import App "./App";

ReactDom.render(
	<React.StrictMode>
		<Router>
			<App />
		</Router>
	</React.StrictMode>
);
```

We next need to go to our `App.js` file or anywhere within our application, we want to add route changes. Within this component, we specify that we are going to add specific routes by using the Routes component that we import from `react-router-dom`. We additionally need to import the route component from `react-router-dom`. This looks something like this:

```jsx
import { Routes, Route } from "react-router-dom";
```

The `Routes` component is responsible for holding the specific route while the `Route` component is responsible for declaring and rendering the specified component linked to the route. In other words, Routes is like a phone book that holds a bunch of names and numbers while the route is an individual name that is connected to a specific phone number.

We can better visualize this by creating a simple navigation bar.

```jsx
import { Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";

const App = () => {
  return (
    <div className="App">
      <Navbar />

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/About" element={<About />} />
        <Route path="/Contact" element={<Contact />} />
      </Routes>
    </div>
  );
};

export default App;
```

As we can see Route is a child of Routes(a wrapper element that holds an individual route). Additionally, a route element can only ever be inside of the Routes wrapper component.

The `route` element has a few attributes:

1. path -> Responsible for specifying the route
2. element -> responsible for rendering the corresponding element

Therefore, saying `<Route path="/About" element={<About />}/>` means that when we navigate to `/About` we should render the about component. The same goes for `/Contact`, we should render the Contact component.

### Navigating

We don't want to be typing specific routes into the URL every time we want to navigate to a different page -- it's time-consuming and your end-user may not know what pages exist on your website. So we need a way to add functional links to our navigation bar. Normally in regular HTML, we can use the anchor tag (`<a></a>`) to add links to our page. While this is still possible to do within react, it is not recommended as this triggers a page refresh -- negating the benefits of a single-page application.

Luckily, `react-router-dom` comes with Link and NavLink components that we can import into our component where we want to add links. We do this by:

```jsx
import { Link, NavLink } from "react-router-dom";
```

Now it's just a matter of using it in our component. It works just the same as the anchor tag, however, instead of an `href` property, we have a `to` property. It looks something like this:

```jsx
<Link to="/About">
  <p>About Page</p>
</Link>
```

So now every time the About Page text is clicked by the user, they will be navigated to the about page.

NavLink works just the same as link but it has an additional active property that can let us know if the current link is active. It adds an active class to the element which we can use to style in CSS.

### Dynamic Routes

We use dynamic routes when we want to create a page for a component that we currently do not have the information for -- We know the layout of the page but the information needed to populate the page is not currently available. This may be due to us needing to get the information from a backend API. For example, let's look at a car company; This company may have different versions of their popular car model A. We as the developer of the website may not know how many versions of Model A exist, so instead of manually creating a page for the different versions of Model A, we can do it dynamically.

We can get a list of the different versions of modal A and then create a specific page for those versions. This allows us to always have the most up-to-date version of the website regarding the version of Model A.

We create a dynamic route in react using `/:` followed by the name of the variable for the route. It looks something like this

```jsx
<Route path="/Model_A/:Version" />
```

Now any route that is after Model_A can be created and be a valid route.

In addition, we can get the route name from the URL using the params element. In our new page, we import the `params` element from `react-router-dom` and then we can destructure that variable to get the name of the page that is created. It looks something like this:

```jsx
import { useParams } from "react-router-dom";

const Example = () => {
  const { Version } = useParams();
};
```

We can then use this variable to do whatever we want really; If we need to make an API call that is dependent on this variable or we just need to display it, we can do that.

### Miscellaneous things

Just wrapping up here, we have a few miscellaneous concepts to cover here.

We can also create navigation using the navigate hook by importing `useNavigate` from `react-router-dom`. We set up a variable and set it equal to the useNavigate hook.

```jsx
const navigate = useNavigate();
```

Now navigate is a function we can call and pass the routes as the argument which navigates us to a specific route.

```jsx
navigate("/About");
```

The above will take us to the About page.

We can also create a back button using this method. Instead of passing in a route, we can pass in **-1** which takes us back 1 page. Now you might be wondering what happens if we pass in **-3**? This will take us back 3 pages. This can happen because as we navigate through our app a history stack is being built and so the navigate function is just looking at the history stack to determine what page to go back to. The back button function looks something like this:

```jsx
navigate(-1);
```

## Conclusion

Now looking at this, there's a lot more that you can do with react-router that we haven't touched on here. The documentation for react-router describes all the features in detail and I've linked it down below. Some of you may have already been using an older version of react-router, V5. There are breaking changes between version 5 and version 6 and the documentation describes how to properly upgrade so that those changes are fixed.

Alright, here is a challenge for you -> build out an application that has a functional navigation menu with the ability to have a back button within the app.

Hope you found this useful, don't forget to smash the like button to catch you in the next one

✌️
]]></content:encoded>
            <author>Nonsoo</author>
            <category>react</category>
        </item>
        <item>
            <title><![CDATA[How do we design algorithms that scale with our data?]]></title>
            <link>https://www.nonsoo.com/posts/designing-algorithms</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/designing-algorithms</guid>
            <pubDate>Mon, 21 Nov 2022 22:13:56 GMT</pubDate>
            <description><![CDATA[Data structures & Algorithms (DSA) may be the bain of every computer science student's existence; it sure was mine. But after contributing to/writing software for small businesses and personal projects, I can appreciate why it's important to learn and its specific use cases. This article explores the sorting algorithms part of DSA's and tours through the importance and use cases of various sorting algorithms.]]></description>
            <content:encoded><![CDATA[
Data structures & Algorithms (DSA) may be the bain of every computer science student's existence; it sure was mine. But after contributing to/writing software for small businesses and personal projects, I can appreciate why it's important to learn and its specific use cases. DSAs allow us to have a structured approach when trying to solve a problem. Whether you are trying to solve the next Leetcode problem or help a business design new software, understanding DSAs serves an important role in software engineering. This article will explore the sorting algorithms part of DSA's and tour through the importance and use cases of various sorting algorithms.

So that we are on the same page, let's first define an **algorithm**: it is a set of instructions that define how a task is to be completed. We're met with algorithms in our daily lives without even thinking about it. For example, think about a chore that is part of your weekly routine -- if you were to automate this chore, how would you go about doing it? What's the first thing you would do? What are the steps in the middle? What's the final step? The list of instructions that you come up with is essentially an algorithm -- a set of instructions that define how to complete a task.

Focusing more on computer science topics, there are many different algorithms that allow us to complete various tasks. One common task for computer scientists/programmers is sorting an iterable list using one of the various sorting algorithms. There are quite a few sorting algorithms and so the question becomes does it really matter which one we pick to solve our problem? I mean at the end of the day we're still sorting a list. In short, yes it matters which sorting algorithm is picked to solve the problem but I think it's more nuanced as it all stems back to the point of efficiency. Although there are many sorting algorithms to choose from, some algorithms are more efficient than others. But how do we determine how efficient an algorithm is?

## Big O notation

The efficiency of an algorithm is measured in a notation known as **Big O** and it's really meant to describe the behaviour of a function/algorithm as the input size grows to infinity. It's used both in computer science and mathematics and it becomes very useful when thinking about how to design scalable algorithms/functions. The algorithm you design might work well when the input size is small but how does it perform as the input size grows? That's what **big O** aims to answer and it's why we look at an input size of infinity when assessing efficiency.

Below is an image describing the different **Big O** notations where the x-axis represents the number of operations and the y-axis represents the performance of the function/algorithm. When we refer to the different **big O** notations, you will often see it denoted as `O(n)` where `O` represents the order of magnitude and `n` represents the number of operations in an algorithm.

![time complexity for big O notation](time_complexity)

Let's say we had a phone book and we wanted to search for a particular name, how would we go about doing it?

1. We could be given the exact location of that name in the phonebook. That way we just have to go to that page and retrieve the information

2. We go look through the phonebook page by page to find the name and information that interests us

3. Assuming the phone book is sorted in alphabetical order, we could use a narrowing down method. We could open the phone book to the middle page and check if the name we want is less than or greater than the names in the middle. Depending on the section, we then open the middle of that respective section; narrowing it down until we find the name of interest.

Of the approaches listed above, one of them is clearly more efficient while other approaches require more steps/operations to accomplish the same task. When designing algorithms, it's important to think about how these algorithms are going to scale and how performant they are going to be at large input sizes. For a phonebook that does not have many pages, option 2 may be a viable method but that becomes less the case as the phonebook grows in size.

## Common Big O complexity

We're going to be looking at some of the common Big O complexities and exploring what they mean on an individual level.

### O(1)

O(1) also known as constant time describes an algorithm that does not change in performance as the input size grows to infinity. These algorithms are very efficient as an input of size 10 and an input size of 1,000,000 will have the same performance.

An example of an operation that has a constant time complexity is looking up an item in an array where we have the index (the location of the item). Since we have the index of the item we want to search for, the size of the array becomes irrelevant as getting the item we want just requires us to go to the location/index in the array, therefore this operation takes the same amount of time. Using the example described above with the phonebook, we can see that option 1 has a constant time operation.

### O(log n)

O(log n) also known as logarithmic time describes an algorithm whose performance grows half as fast in proportion to the size of the input. Therefore, at very large input sizes, the change in performance of a logarithmic algorithm is small. You mostly see logarithmic functions in recursive functions and binary search algorithms. Using the example described above with the phonebook, we can see that option 3 operates in logarithmic time.

> In computer science when we speak of logarithms, we assume a base of 2 unless otherwise stated.

### O(n)

O(n) also known as linear time describes an algorithm whose performance grows linearly and in direct correlation to the input size. Therefore, the increased input size leads to a proportional increase in run time. Going back to the scenario above, looking through the phonebook page by page to find your name of interest would have a time complexity of O(n). Since it would take `n` operations to find the name of interest in a phone book of size `n` names. A common example of an O(n) operation is iterating a list of size n to do some operation. Using the example described above with the phonebook, we can see that option 2 operates in linear time.

### O(n log n)

O(n log n) also known as log-linear time describes an algorithm that performs `log n` operations `n` times. The run time of an algorithm with this time complexity grows with the size of the input (almost linearly) although we perform a `log n` operation at each step. We are performing extra steps when compared to an `O(n)` time complexity therefore we say that an algorithm with an `O(n log n)` time complexity is less efficient than an algorithm with an `O(n)` time complexity.

### O(n^2)

`O(n^2)` also known as quadratic time describes an algorithm whose performance exponentially increases in correlation with the input size. The performance of the algorithms gets much slower as the input size grows to infinity. At every step, we perform an `n` operation therefore we say that an algorithm with an `O(n^2)` time complexity is less efficient than an algorithm with an `O(n)` or `O(n log n)` time complexity. This is commonly seen with nested loops **although nested loops do not always mean a time complexity of `O(n^2)`**.

## Sorting Algorithms

As I alluded to above, a common thing that computer programmers do is retrieve data, sort data, and search through data. Many sorting algorithms can be used to complete these tasks and it's left to the developer to decide & implement the appropriate one for the job. To appropriately make this decision, the developer must think about how the data will scale because this choice will impact the efficiency of the overall application.

Below are some examples of sorting algorithms that are available for use. This is just a very short list so there are more than just the ones listed below.

<Aside title="Note" tag="Note">
  It's important to note that the concepts and examples we're about look at do
  not include any particular programing languages because I think it's important
  first understand the concept before writing the code. For these examples, I
  remain language agnostic but I encourage you to implement these concepts in
  the language of your choosing.
</Aside>

### Bubble Sort

I find that **bubble sort** is the easiest sorting algorithm to conceptually think about as larger items are progressively being moved to the top of the list. People often say that with **bubble sort** larger items are bubbled up to the top. Bubble sort compares two adjacent elements and if the current item in the list is greater than the next item in the list, a swap will occur. This is done for the entire length of the list, thus leading to a sorted list.

<SortingAlgoListItem />

Suppose we are trying to sort the following array of numbers in ascending order, using bubble sort the following will occur:

1. Starting from the first index, compare the first and the second elements.
2. If the first element is greater than the second element, they are swapped.
3. Now, compare the second and the third elements. Swap them if they are not in order.
4. The above process goes on until the last element.

Using the demo below, try to implement the bubble sort algorithm.
<SortingAlgo_SortDemo />

This occurs for the length of the entire list and until the entire list is sorted. In its worst case, the bubble sort algorithm has a time complexity of `O (n^2)`, therefore it would not be recommended for use with large data sets. As mentioned above an algorithm with a time complexity of `O(n^2)` does not scale very well.

### Selection Sort

Selection sort selects the smallest element from an unsorted list in each iteration and places that element at the beginning of the unsorted list.

<SortingAlgoListItem />

Suppose we are trying to sort the following array of numbers in ascending order, using selection sort the following will occur:

1. Set the first element in the list as the `minimum` value
2. Compare `minimum` with the second element. If the second element is smaller than `minimum`, assign the second element as `minimum`.
3. Compare `minimum` with the third element. Again, if the third element is smaller, then assign `minimum` to the third element otherwise do nothing. The process continues until the last element.
4. The minimum item is moved/swapped into the sorted half of the list -- this is in front of the first unsorted item in the list.
5. Indexing then starts from the first unsorted item and steps 1 - 4 are repeated.
6. This occurs for the length of the entire list and until the entire list is sorted.

Below you will find an interactive example of selection sort in action. The green inner box represents the sorted array that is going to be created while the outer box represents the unsorted array. Drag the following numbers into the sorted array section and at each iteration, you're going to pick the smallest number from the unsorted array section.

<SortingAlgo_SelectionSort />

In its worst-case and best-case, the selection sort algorithm has a time complexity of `O (n^2)`. The time complexity of the selection sort is the same in all cases as at every step, you have to find the minimum element and put it in the right place. The minimum element is not known until the end of the array is not reached. Therefore, this algorithm would not be recommended for use with large data sets.

### Insertion sort

Insertion sort places an unsorted element at its suitable place in each iteration -- it works similarly as we sort cards in our hand in a card game.

<SortingAlgoListItem />

Suppose we are trying to sort the following array of numbers in ascending order. Using insertion sort the following will occur:

1. We split our unsorted list into a sorted and unsorted section
2. We assume that the first item in the list is already sorted so we look at the second item
3. We move the second item( herein denoted as `currItem`) into the sorted section of the list and compare it to previous values in the sorted section
4. If the `currItem` is less than its previous value, then we swap the previous value with `currItem`
5. This is done for the entire length of the sorted section. If `currItem` is greater than its previous value then we stop and move on to the next item in the unsorted section

This occurs for the length of the entire list and until the entire list is sorted. In the demo below, you can drag the numbers around to get a sense of how to implement the insersion sort algorithm.

<SortingAlgo_SortDemo />

In its worst case, the insertion sort algorithm has a time complexity of `O (n^2)` while in its best case the insertion sort algorithm has a time complexity of `O(n)`. The worst-case may occur if you want to reserve an array that is in ascending order -- put the array into descending order. Each element has to be compared with the other elements thus leaving you with `n(n-1)` -- this gives you the `n^2` time complexity. The best case may occur if the array is already sorted since you would not need to perform a sort in the **sorted section** of the array.

### Quick Sort

The quick sort algorithm is based on the **Divide and Conquer** paradigm as the array is initially divided into two halves and then later combined in a sorted manner. It selects an element as a pivot value and then partitions the given array around the selected pivot value. Elements that are less than the pivot are placed to the left while elements that are greater than the pivot are placed to the right of the pivot element. This way the pivot value is considered sorted.

Here's a guide to the first iteration of the quick-sort algorithm. From the number is the array presented below,

<SortingAlgoListItem />

1. select a pivot value
2. move all the elements that are less than the pivot to the left box
3. move all the elements that are greater than the pivot value to the right box
4. This is done recursively until the entire array/list has become sorted.

In its worst case, the quick sort algorithm has a time complexity of `O (n^2)` since there may be a case where the pivot element selected is the greatest or smallest element in the list. This creates a case where all the elements are on the extreme end of the array thus having one sub-array always being empty while the other contains `n-1` elements. For this reason, the quicksort algorithm is best performed when there are scattered pivot points. In its best case, the quick sort algorithm has a time complexity of `O(n log n)` since there may be cases where the pivot element selected is always the middle element or near to the middle element.

On average quicksort has a time complexity of `O(n log n)` and a space complexity of `O(log n)`.

### Merge Sort

The merge sort algorithm is based on the **Divide and Conquer** paradigm as the array is initially divided into two halves and then later combined in a sorted manner. It's often thought of as a recursive algorithm that constantly splits an array or sub-arrays into smaller units until it reaches the base case where it cannot be divided anymore. The individual items are then merged back together in sorted order which produces the original array that is now sorted. Below is an image describing the merge sort algorithm.

![merge sort algorithm](merge_sort)

In its worst-case and best-case, the **merge sort** algorithm has a time complexity of `O(n log n)`. This is really good in terms of efficiency, however, **merge sort** also has a space complexity of `O(n)`. Therefore, as the input size grows, the space needed to complete this algorithm grows proportionally. Essentially we're making a tradeoff in terms of efficiency for space.

<Aside title="Fun fact!" tag="FYI">
  In JavaScript when you use the `.sort()` method, some browsers actually
  implement the merge sort algorithm whereas others use either selection sort or
  the quick sort algorithm. It's all dependent on the JavaScript engine
  specified by that browser so if you want to remain consistent across multiple
  browsers then you may want to write your own sorting algorithm -- it's quite
  fun to implement!
</Aside>

## To wrap up

Algorithms are very useful functions that abstract away a lot of logic and they make developer lives so much easier. Algorithms allow developers to write instructions once and then implement them everywhere thereby allowing developers to focus on writing the application. The best algorithm takes into account how the data it receives will scale so as to maximize efficiency. So, whether you are trying to solve the next Leetcode problem or help a business design new software, understanding how to best implement algorithms serves an important role in software engineering.

Hope you found this useful, don't forget to smash the like button and I'll catch you in the next one... Peace!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>programming</category>
        </item>
        <item>
            <title><![CDATA[Selecting parent elements has become easier]]></title>
            <link>https://www.nonsoo.com/posts/the-has-selector</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/the-has-selector</guid>
            <pubDate>Mon, 21 Nov 2022 22:07:52 GMT</pubDate>
            <description><![CDATA[CSS has a lot of ways to select elements in the HTML and so many options can make it difficult to choose which method is most sufficient. The :has selector gives us another way to select parent elements but it allows us to do so much more. Here we deep dive into what the :has selector is and explore different use cases]]></description>
            <content:encoded><![CDATA[
CSS has a lot of ways to select elements in HTML and so many options can make it difficult to choose which method is most sufficient. This becomes very apparent when we have multiple elements on the pages that share styles but one of them, in particular, has a different style than the rest.

{/* <!--- Show a component with three cards and the middle and the middle one is different ---> */}

<CardComp />

The traditional way to solve this problem is to place another CSS class on the component that is going to get this **Special style**. It may look something like this

```html
<div class="card">...Some content goes here</div>
<div class="card special-card">
  ...Some content goes here
  <p class="card__subTitle">Some more content for the special class</p>
</div>
<div class="card">...Some content goes here</div>
```

The middle `div` element has two CSS classes: 1) one denoting that it will get all the styles in the card class and 2) denoting that it will get all the styles from the special-card class.

There hasn't really been a way to select an element with CSS if it has certain descendants -- at least not until recently.

## The HAS Selector

The `:has` selector also comically known as the parent selector is a pseudo-class that was introduced in the CSS spec. `:has` allows for the selection of an element if the arguments passed into `:has` match at least one element when anchored against the parent element. Essentially it allows for the selection of an element based on the presence or absence of descendant elements.

Revisiting our example above, let's say our special card had a paragraph that implemend its own padding in the in-line direction. Since we want all the cards to have the same amount of padding we need some way of addressing this problem. We can reach for the solution above, or we can implement the `:has` selector. We can select the card if it has a paragraph as its child and then set the in-line padding on the card to 0. It looks something like this:

```css
.card:has(.card__subTitle) {
  padding-inline: 0;
}
```

The above code block translates to if an element with the class of `.card` has a descendant with the class of `.card__subTitle` then set the in-line padding on the parent element (in this case the element with the class of `.card`) to 0.

**Pop quiz!!!**

```html
<div class="card">...Some content goes here</div>
<div class="card special-card">
  ...Some content goes here
  <p class="Title">Some more content for the special class</p>
</div>
<div class="card">...Some content goes here</div>
```

<HAS_SELECTOR_QUIZ_1 />

### Multiple selectors inside has

The cool thing is that we aren't just limited to putting one item inside the `:has` pseudo-class. We can chain on selectors and get really specific as to when we want this `parent element` to be selected. Chaining on selectors looks something like this:

```css
.card:has(.card__subTitle, .Title) {
  padding-inline: 0;
}
```

The above code block translates to if an element with the class of `.card` has a descendant with the class of `.card__subTitle` **or** `.Title` then set the in-line padding on the parent element (in this case the element with the class of `.card`) to 0.

You might have noticed the keyword **OR** above. This is important and a key differentiator between `:has` and other selectors. Usually with CSS if you are chaining selectors, if one of the selectors in your chain does not match, then the entire rule is skipped. This is not the case with the `:has` pseudo-class, and it is something that differentiates it from other selectors. As long as there is one matching selector inside the `:has` pseudo-class, then the parent element will be selected.

You might be wondering how we may go about saying **AND** with this selector. More specifically how do we go about saying the following: Select the element with the `.card` class if its descendants have elements with the `.first` **and** `.second`classes. Using the scenario above `.card:has(.first .second)` matches at least one. What happens if we require both to be present?

We can attach another `:has` pseudo-class. It would look something like this:

```css
.card:has(.first):has(.second) {
  padding-inline: 0;
}
```

The above code block translates to if an element with the class of `.card` has a descendant with the class of `.first` **and** `.second` then set the in-line padding on the parent element (in this case the element with the class of `.card`) to 0.

The other cool thing about `:has` is that we can chain complex selectors when the `parent element` is to be selected. We can say something like this:

```css
.card:has(> .first .title) {
  /* Some css rule */
}
```

Only select an element with a `.card` class if it has direct decedents with a class of `.first` which has a descendent with a class of `.title`.

### More than just a parent Selector

The `:has` pseudo-class is more than just a parent selector because we can use it to select other elements that are in relation to the parent element. The following describes how we are using the `:has` pseudo-class to select a paragraph element.

```css
.card:has(.subTitle) > p {
  /*Some Css Rule */
}
```

The above code block translates to: select any paragraph element that is a direct decedent of `.card` if the `.card` has a descendant element with the `.subTitle` class. Putting this into practice, below we can see that the manager's name is in **bold** while the staff's name is not. This is being done with a rule similar to the one we described above.

{/* <!--- Place a demo that shows two separate cards. one being selected and the other not being selected ---> */}

<CardDemo />

## Specificity

Calculating specificity with the `:has` pseudo-class gets a bit complicated and so we are going to walk through an explanation and then some examples.

Let's say we have the following scenario:

```css
.card:has(.first p) {
  /* Some css rule */
}
```

What is the specificity here? We first look at the selector outside the `:has` pseudo-class and then focus on the selectors inside the `:has` pseudo-class. Here we have `1 class` selector outside `:has` and then `1 class selector` & `1 element selector` inside `:has`. Therefore, we say that the specificity of the entire selector is `2 class selectors` & `1 element Selector`.

{/* <!---  Question: calculate the specificity on the following selector ---> */}

<HAS_SELECTOR_QUIZ_2 />

The interesting thing is that calculating specificity changes when there are multiple selectors inside the `:has` pseudo-class that are separated by a comma. In this case `:has` will only use the specificity of the most specific selector. This is demonstrated below:

```css
.card:has(.first, p) {
  /* Some css rule */
}
```

What is the specificity here? Remember, we first look at the selector outside the `:has` pseudo-class and then focus on the selectors inside the `:has` pseudo-class. Here we have `1 class` selector outside `:has` & `1 class selector` & `1 element selector` inside `:has`. Since the **class selector** and the ** element selector** are separated by a comma, we look at the selector with the highest specificity. In this case, it would be the class selector. Therefore, we say that the overall specificity is `2 class selectors`.

In the case where we have multiple `:has` pseudo-classes, we calculate the specificity for the individual `:has` and then combine them all to get an overall specificity. The following is an example of this:

```css
.card:has(.first):has(.second p) {
  padding-inline: 0;
}
```

Here we have `1 class` selector outside `:has`, `1 class selector` inside the first `:has`, and `1 class selector` & `1 element selector` inside the second `:has`. These specificities are all combined to give us an overall specificity of **3 classes** and **1 element**.

{/* <!---  Question: calculate the specificity on the following selector ---> */}

<HAS_SELECTOR_QUIZ_3 />

## Browser support

According to [Can I use](https://caniuse.com/) as of the time of writing this article the `:has` pseudo-class is at 76% support in terms of browsers. Moreover, it is supported in the latest version of Chromium & Safari, and it is under an experimental flag in firefox (thus I expect it to be fully supported in firefox fairly soon).

## Conclusion

This `:has` selector is an incredible selector and it gives us another way to author the CSS for our applications. I can't wait for it to be fully supported across all major browsers!

Alight I'll catch you in the next one -> peace out!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>CSS</category>
        </item>
        <item>
            <title><![CDATA[Dark Mode: Not as simple as inverting the colours]]></title>
            <link>https://www.nonsoo.com/posts/dark-mode-css</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/dark-mode-css</guid>
            <pubDate>Mon, 21 Nov 2022 21:49:42 GMT</pubDate>
            <description><![CDATA[ark mode, a fan favourite amongst developers and user alike. I find that there are a lot of nuances about creating dark theme for a website/application that are missed -- it isn't really as simple as inverting the colour scheme of your website/application. In this article we will explore some of those nuances and find how to create an effective dark theme.]]></description>
            <content:encoded><![CDATA[
## Introduction

Dark mode, a fan favourite amongst developers and user alike. Today we will be taking a look at how to implement dark mode in a web application. As always, there are a number of ways to accomplish this with some including the use of JavaScript but today, we are strictly sticking with css.

## Getting Started

Before diving in, lets talk about what it means to implement dark mode in your application. I find that the natural/default interpretation of dark mode is just the inversion of colour -- making a light background dark while making the dark text light. However, I've come to realize that it is not that simple; I amy be wrong but that's just my interpretation.

Usually the way we create depth in a "light" setting is by using shadows to make our piece of content, say a card component, stand out from the background. In a "Dark" setting using this trick most often look very weird and adds distractions to the UI. In the same way using vibrant and very contrasty colours may work very well in a "light setting" but don't work as well in a dark setting. To create depth in dark mode, we may want to think about using lighter less saturated colours between our component and the background to create a degree of separation. So picking your colours for both modes becomes very important when thinking about adding a dark mode to your application.

## Implementing Dark mode

At the end of the day dark mode is a preference, some of your users may not prefer a dark theme and so you would want a way to give users a choice. Luckily, css provides a way to for developers to know what type of theme a user prefers. This is done with using the:

```css
@media (prefers-color-scheme);
```

This is a css media features that is widely supported across browsers and it is used to detect whether a user prefers a light or dark theme. More specifically, this is done by looking at the device colour scheme preferences that is set by the user.

`@media (prefers-color-scheme)` takes in one of three values: `Initial`, `light`, or `dark`. By default initial is selected if these parameters are not specified. Setting it to light indicates that the user prefers a light theme while setting it to dark indicates that the user prefers a dark theme. Example written below:

```css
@media (prefers-color-scheme: initial) {
}
```

```css
@media (prefers-color-scheme: light) {
}
```

```css
@media (prefers-color-scheme: dark) {
}
```

Inside the curly braces we can then specify the class, id or element to target but doing this may be time consuming and there may be better more efficient ways to do this. Instead, it may become very useful to use css custom properties. The value of doing this is that we can set custom colour schemes and then change the colours that are assigned to the variables based on if the user wants a light or dark theme.

On the root element set your colours in css variables and then for dark mode simply just switch the colours. Example below:

```css
:root {
  --background-Clr: #f9f8fa;
  --background-Clr-sec: #ffffff;
  --prmy-text-color: #171717;
  --sec-text-color: #ffffff;
}

@media (prefers-color-scheme: dark) {
  :root {
    --background-Clr: #282828;
    --background-Clr-sec: #141414;
    --prmy-text-color: #ffffff;
    --sec-text-color: #171717;
  }
}
```

> **You may also need to target additional classes or ids to fine tune the colour scheme.**

Now that this is complete we have a way to set a light and dark colour scheme based on the users system preferences and without implementing any javascript

---

Check out the youtube channel to see how we are implementing the feature in the app we are building! [letsCreate: Dark mode using CSS](https://www.youtube.com/watch?v=dSH5tgPUvfw)
]]></content:encoded>
            <author>Nonsoo</author>
            <category>css</category>
        </item>
        <item>
            <title><![CDATA[Let's not over-engineer things]]></title>
            <link>https://www.nonsoo.com/posts/lets-not-over-engineer-things</link>
            <guid isPermaLink="false">https://www.nonsoo.com/posts/lets-not-over-engineer-things</guid>
            <pubDate>Mon, 21 Nov 2022 21:47:42 GMT</pubDate>
            <description><![CDATA[Games like Wordle, Clueless Words, Nerdle, and so on somehow generate a new word/puzzle every day. It's an aspect of these games that are not thought about from the player's perspective at least not until one of the players tries to build a daily puzzle. In this article, I explore different ways to pick a new word/puzzle every day and the pros & cons of each approach.]]></description>
            <content:encoded><![CDATA[
Not too long ago, I created a game called [clueless words](https://cluelesswords.com) -- a daily word game where users use a list of synonyms to a word to find the secret word for the day. I'm fully biased here but I would say it's quite fun to play every day.

One of the things that I had to think about when creating the game was how new words were going to be generated every day. More specifically, was there a way to pick a word from a list and then have this done daily? To be fair after taking a closer look into how to go about solving the problem, numerous solutions started to pop up. I was looking for the most optimal solution though; After all, just because there is a solution to a problem doesn't mean that it is the most optimal solution. Let's think about the problem -- we want a way to generate a random word every day when a user visits the website. How do we do this? We're going to be going over some solutions and then I'll walk you through the implementation of my solution.

## Option 1

People have dedicated their time to making APIs that generate random words when that API receives a request. This is one part of the problems solved and we can use this in our game, however, it opens up another problem. How do we make this API request recurring? We need new words every day so we would need a way to tell the server to generate a new word on a new day. One option would be to set up what is known as a CRON job.

<Aside title="FYI" tag="FYI">
  CRON is a job scheduler that is set up on a Unix-like machine where users set
  up and maintain software environments that run periodically at fixed times,
  dates, or intervals. Therefore, CRON is most suitable for scheduling
  repetitive tasks.

  <Expanded>
    There are many ways to create CRON jobs but I find that the two easiest methods are 1) using GitHub actions or 2) using a node.js application. For GitHub actions you setup CRON as part of your workflow while in Node.Js there is the [cron](https://github.com/kelektiv/node-cron) library that simplifies the process of working/setting up with cron jobs.

    Another useful tool that simplifies the process of working with CRON is the [crontab](https://crontab.guru) website. I like this tool because it helps you translate CRON schedule expressions into readable date-times.

  </Expanded>

</Aside>

The CRON job would be responsible for calling a serverless function that makes an API request to the random word generator API and this would occur daily. This solves our problem of generating random words which we can then use in the game but it comes at an extra cost. We now have to determine how we are going to set up a CRON job in the cloud and more importantly, we have to now setup alongside our serverless function.

Another approach is that we gather a list of words and we store it in a database. We can then build an API that increments through our database of words daily. We can also implement our previous approach of working with a CRON job to help us get a new word from our database. This is also a good approach but we now have to worry about configuring a database, building that API and then serving everything.

While these solutions are viable options for solving our problem, these approaches add a lot of complexity that may not be needed. They may be more optimal solutions to our problem.

## Option 2

After scouring the internet, listening to a few podcasts, and quite a few days spent trying to come up with a solution, I finally landed on the idea of "Why don't we just index an array of words every day?". We would essentially just store our list of words in JSON form and when a user makes a request to the website the array of words would be indexed to get the word for that day. This is a simpler solution but it also poses another problem -- how do we index an array every day?

What I realized was that the way the index was generated was important and crucial to what word was going to be shown on any given day. In that regard, it would mean that the index generated for the word list would have to become date specific. Essentially the index could represent the time in days that have elapsed from when the game was released -- we call the offset date. Naturally, as time progresses, this offset date would also increase in value day after day. We can then use this offset date to index our array of words and naturally have a new word every day as time progresses. There is no need for any databases, API requests, or CRON jobs as everything in terms of generating new words every day for the game is handled by this function. All we have to do is supply the array, the current date, and the date the game was released to get a new item generated every day.

Although this approach presents its downfalls as the wordlist has to be local, I think it's cool and simplistic in terms of its setup. We're going to be walking through an implementation of the functions in JavaScript, but they can be done in any programming language.

We first have to create our helper function called calculate offset date:

```js
const getOffSetDate = (currentDate, baseLineDate) => {
  const offset = currentDate - baseLineDate;
  const toDaysConverter = 24 * 60 * 60 * 1000;
  const convertToDaysNumber = Math.abs(Math.floor(offSet / toDaysConverter));

  return convertToDaysNumber;
};
```

This function takes in a `currentDate` and `baseLineDate` as its arguments and calculates an offset number by subtracting the `baseLineDate` from the `currentDate`. Since the JavaScript data object returns values in terms of milliseconds, our current `offset` number is in milliseconds. For our next function, we need to get a representation of the time in days, therefore, we have to convert our `offset number` to days.
Things to note are that we're using `Math.floor` to ensure that we do not have a decimal value but more importantly to ensure that we are appropriately accounting for one full day. We are then taking the absolute value to ensure that we do not have any negative values.

We now have to create a function that is going to return a single word from a word list that is passed in as an argument.

```js
const getTodaysWord = (WordLst) => {
  const todaysDate = new Date();
  const baseLineDate = new Date("October 02, 2022 00:00:00 UTC");

  const indexArray = getOffSetDate(todaysDate, baseLineDate);

  const todaysWord = WordLst[indexArray];

  return todaysWord;
};

export default getTodaysWord;
```

Inside our new `getTodayWord` function, we have to initialize two variables that are going to represent `todaysDate` and the `baseLineDate`. We then call our `getOffSetDate` function, pass in the two variables and then store the return value in a new variable called `indexArray`. Remember the return value of `getOffSetDate` is a number that represents that time in **days** that have elapsed from the `baseLineDate`. We now use this value as an index for our `WordLst` to get a single word for the respective day.

## Conclusion

YAY!! We've built a way to generate a new word daily without the need for any databases, API requests, or CRON jobs as everything in terms of generating new words every day for the game is handled by the functions above. Although there are still downfalls with this approach, I believe it provides a simple and elegant way of generating a new word/puzzle every day.

Hope you found this useful, don't forget to smash the like button and I'll catch you in the next one... Peace!
]]></content:encoded>
            <author>Nonsoo</author>
            <category>programming</category>
        </item>
    </channel>
</rss>