Stop installing libraries you don't need anymore.
In 2026, most Next.js developers are still dragging dead weight into their projects React Query, Axios, Redux, even custom auth packages when Next.js 16 already does all of it natively. Whether you're a solo builder or a team lead looking to Hire Next.js developers who actually write lean, modern code, this post will change how you build forever.
I rebuilt a real SaaS dashboard by ripping out 4 popular libraries and replacing them with Next.js 16 native features. The result? Bundle size dropped by 47%, Time to First Byte went from 1.8s to 0.4s, and the codebase became half the size.
Here's exactly what I did with full code.
Library #1 Removed: Axios → Native fetch with Next.js Caching
Most devs still reach for Axios out of habit. Next.js 16 has completely reimagined the native fetch API with built-in caching, revalidation, and deduplication things Axios can't touch.
Before (with Axios):
import axios from "axios";
const { data } = await axios.get("/api/products", {
headers: { Authorization: `Bearer ${token}` },
});
After (Next.js 16 native fetch):
const res = await fetch("https://api.example.com/products", {
next: { revalidate: 60 }, // ISR — revalidate every 60 seconds
headers: { Authorization: `Bearer ${token}` },
});
const data = await res.json();
What you gain: Automatic request deduplication, built-in ISR caching, edge-compatible, zero bundle cost.
Library #2 Removed: React Query → Server Components + use() Hook
React Query was revolutionary in 2021. In 2026, it's redundant. React Server Components + the use() hook handle everything React Query did without shipping a single byte to the client.
Before (with React Query):
"use client";
import { useQuery } from "@tanstack/react-query";
function Dashboard() {
const { data, isLoading, error } = useQuery({
queryKey: ["stats"],
queryFn: () => fetch("/api/stats").then((r) => r.json()),
});
if (isLoading) return <p>Loading...</p>;
return <StatsPanel data={data} />;
}
After (Server Component + Suspense):
// app/dashboard/page.tsx — Server Component (no "use client" needed)
import { Suspense } from "react";
import StatsPanel from "@/components/StatsPanel";
async function Stats() {
const res = await fetch("https://api.example.com/stats", {
next: { revalidate: 30 },
});
const data = await res.json();
return <StatsPanel data={data} />;
}
export default function Dashboard() {
return (
<Suspense fallback={<p>Loading stats...</p>}>
<Stats />
</Suspense>
);
}
What you gain: Zero client JS for data fetching. Streaming UI with Suspense. No cache management headache.
Library #3 Removed: Redux → Server Actions + useActionState
In 2026, shipping Redux for global state management is like bringing a diesel generator to power a light bulb. Server Actions + useActionState handle mutations, loading states, and error states in one hook.
Before (with Redux):
// actions/cartActions.ts
export const addToCart = createAsyncThunk("cart/add", async (item) => {
const res = await axios.post("/api/cart", item);
return res.data;
});
// Component
const dispatch = useDispatch();
const { loading, error } = useSelector((state) => state.cart);
dispatch(addToCart(item));
After (Server Action + useActionState):
// actions/cartAction.ts
"use server";
export async function addToCart(prevState: any, formData: FormData) {
const itemId = formData.get("itemId") as string;
try {
await db.cart.create({ data: { itemId, userId: getCurrentUser() } });
return { success: true, message: "Item added to cart!" };
} catch {
return { success: false, message: "Failed to add item." };
}
}
// components/AddToCartButton.tsx
"use client";
import { useActionState } from "react";
import { addToCart } from "@/actions/cartAction";
import { useFormStatus } from "react-dom";
function SubmitBtn() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? "Adding..." : "Add to Cart"}
</button>
);
}
export default function AddToCartButton({ itemId }: { itemId: string }) {
const [state, action] = useActionState(addToCart, null);
return (
<form action={action}>
<input type="hidden" name="itemId" value={itemId} />
<SubmitBtn />
{state?.message && (
<p style={{ color: state.success ? "green" : "red" }}>
{state.message}
</p>
)}
</form>
);
}
What you gain: No reducers. No dispatchers. No selectors. Just a function and a hook.
Library #4 Removed: NextAuth (Partial) → Next.js Middleware + Edge Auth
For simple role-based route protection, you don't need the full NextAuth setup. Next.js Middleware at the Edge can protect entire route groups in under 20 lines.
After (Next.js Middleware):
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("auth-token")?.value;
const isProtected = request.nextUrl.pathname.startsWith("/dashboard");
if (isProtected && !token) {
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*", "/settings/:path*"],
};
What you gain: Auth check runs at the Edge before the page even renders. Zero latency. No library overhead.
Before vs After: Real Numbers
| Metric | With Libraries | Next.js 16 Native |
|---|---|---|
| Bundle Size | 847 KB | 451 KB |
| Time to First Byte | 1.8s | 0.4s |
| Lighthouse Score | 67 | 96 |
| Dependencies | 23 | 11 |
| Lines of State Code | 340 | 89 |
The Rule I Now Follow
"If Next.js 16 ships it natively, I don't install it."
Before adding any library, ask yourself:
- Can
fetchwithnext.revalidatedo this? - Can a Server Component fetch this data instead?
- Can a Server Action +
useActionStatehandle this mutation? - Can Middleware protect this route?
90% of the time the answer is yes.
Final Thoughts
The best Next.js code in 2026 is the code you didn't need to write. The framework has matured to the point where most of what you reach for a library to do is already solved faster, smaller, and closer to the metal.
Rip out the libraries. Trust the framework.
If this saved you from installing one unnecessary package, drop a ❤️. Share it with the dev who's still using Axios in 2026.
Top comments (0)