All Articles

A peep into my TechStack

A quick look at the tools, libraries, and frameworks I use to build modern React applications, from state management to styling, and everything in between. Here’s a quick breakdown of the tools and libraries I use regularly in production React apps — and when I use each one.

React Query, Mantine, Tailwind, @ibnlanre/builder, Redux

React Query

For: Asynchronous data fetching and caching.

React Query simplifies data management by abstracting fetch logic, caching, background updates, and stale handling. It avoids redundant requests and keeps the UI in sync with the backend state with minimal boilerplate.

import { useQuery } from "@tanstack/react-query"

function Users() {
  const { data, isLoading } = useQuery(["users"], () =>
    fetch("/api/users").then(res => res.json())
  )

  if (isLoading) return <div>Loading...</div>
  return <pre>{JSON.stringify(data, null, 2)}</pre>
}

@ibnlanre/builder

For: Centralized query options management.

This utility helps structure React Query configurations consistently — especially useful when managing a growing number of endpoints or shared query behaviors like stale time, retry logic, and suspense settings.

import { createBuilder } from "@ibnlanre/builder"

interface AuthPayload {
  username: string
  password: string
  fcm_token: string | undefined
}

const builder = createBuilder({
  auth: {
    login: (payload: AuthPayload) => axios.post("/auth/login", payload),
  },
})

// Integrating with React Query

const { data, status } = useQuery({
  queryKey: builder.auth.login.$get,
  queryFn: builder.$use.auth.login,
})

TypeScript

For: Type safety and DX.

It catches errors before runtime, improves autocomplete, and makes code self-documenting. Every piece of logic is clearer and safer when types are enforced across components, services, and APIs.

type User = {
  id: string
  name: string
}

const user: User = { id: "1", name: "John" }

Routing: Next.js / TanStack Router / React Router

I use these depending on the use case:

  • Next.js when I need server-side rendering, static generation, or easy full-stack integration.
  • TanStack Start for fine-grained routing in React SPAs that don’t need SSR, with strong React Query synergy.
  • React Router for client-side routing in smaller projects or apps that don’t need a framework layer.

Each has its niche. Next.js excels in SEO-driven apps, while TanStack and React Router are lighter and better for highly interactive frontends.

Context API

For: Lightweight state management.

Used when state is local to a part of the app — like theme toggles, user preferences, or modal state. It’s simple, built-in, and avoids external dependencies.

Redux Toolkit

For: Complex, global state management.

When state needs to be shared across many components and involves normalized data, side effects, or persistence (e.g., forms, wizards, user sessions), I use Redux Toolkit. It reduces boilerplate and integrates cleanly with TypeScript.

import { configureStore, createSlice } from "@reduxjs/toolkit"

const counterSlice = createSlice({
  name: "counter",
  initialState: 0,
  reducers: {
    increment: state => state + 1,
  },
})

export const { increment } = counterSlice.actions

const store = configureStore({
  reducer: { counter: counterSlice.reducer },
})

Mantine.dev

For: UI components and layout.

Mantine provides accessible, customizable, and modern components out of the box. Its hooks (e.g. for modals, notifications) save time, and the styling API works well alongside Tailwind when needed.

import type { PropsWithChildren } from "react"
import { MantineProvider, createTheme } from "@mantine/core"
import { Notifications } from "@mantine/notifications"

const theme = createTheme({
  colors: {
    app: [], // Array with 10 colors to generate the color palette for this color scheme
  },
})

const Providers = ({ children }: PropsWithChildren) => {
  return (
    <MantineProvider theme={theme}>
      <Notifications position="top-center" autoClose={5000} />
      {children}
    </MantineProvider>
  )
}

TailwindCSS

For: Utility-first styling.

I use Tailwind for layout, spacing, and utility classes — especially for quick prototyping and consistent design systems. It pairs well with Mantine by covering layout and grid systems, while Mantine handles component logic.

<button class="bg-blue-500 text-white py-2 px-4 rounded-lg">Submit</button>

Final Thoughts

This stack isn’t set in stone. It evolves as projects grow and requirements shift. But this combination gives me control, performance, and developer speed — without sacrificing scalability or maintainability.

Published May 8, 2025

Hey there! I'm Hemense, a Frontend Developer with 4 years of experience developing scalable, high-performance web applications in SaaS, fintech, ERP, and AI-driven solutions. I am skilled in building component-driven architectures, improving user engagement, reducing churn, and optimizing platform performance for revenue growth. I have experience with React, TypeScript and its ecosystem. I am passionate about data- driven development, design systems, and engineering best practices to drive impactful user experiences.