DEV Community

Cover image for We Cut 70% Bundle Size: TanStack Query + Zustand at GLINR
GDS K S
GDS K S

Posted on

We Cut 70% Bundle Size: TanStack Query + Zustand at GLINR

The Problem: Complexity Without Benefits

Three months ago at GLINR, our AI-powered developer platform was shipping 50kb of Apollo Client just to fetch billing quotas and user data.

As the lead architect (GDSKS here), I kept asking: "Are we actually using these features?" The answer was uncomfortable: we were using about 10% of what Apollo offered.

What We Actually Needed

The Metrics That Made Us Act

Metric Value Status
Apollo Bundle 50kb gzipped Too large
Cache Complexity High Unused
Time to Interactive 2.8 seconds Slow
Developer Confidence 6.2/10 Low
Features Used ~10% Wasteful

The Solution: Architectural Separation

The breakthrough came from a simple realization: server state and client state are fundamentally different.

The Core Principle

State Classification

State Type Characteristics Best Tool Example
Server State Asynchronous, cached, needs sync TanStack Query API data, user info, billing
Client State Synchronous, local, ephemeral Zustand Modals, themes, form wizards

Architecture Deep Dive

Before: The Apollo Monolith

Pain Points:

  • Mixed responsibilities (server + client state)
  • Unclear patterns for UI state
  • Complex cache invalidation
  • 50kb bundle for basic queries

After: Clean Separation

Benefits:

  • Clear separation of concerns
  • Each tool optimized for its purpose
  • 18kb total bundle
  • Obvious patterns for developers

How Data Flows: The Complete Picture

Query Lifecycle with TanStack Query

State Updates with Zustand


Real Implementation at GLINR

The Code: Less Is More

Here's the minimal code needed to get started:

Setup TanStack Query (5 lines):

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient({
  defaultOptions: { queries: { staleTime: 60000 } }
});

// Wrap app



Enter fullscreen mode Exit fullscreen mode

Setup Zustand (8 lines):

import { create } from 'zustand';

export const useAppStore = create((set) => ({
  activeOrgId: null,
  theme: 'light',
  setActiveOrg: (id) => set({ activeOrgId: id }),
  setTheme: (theme) => set({ theme }),
}));
Enter fullscreen mode Exit fullscreen mode

Using Both Together:

// Component code
const { data: quotas } = useQuery({
  queryKey: ['quotas', orgId],
  queryFn: fetchQuotas
});

const { theme, setTheme } = useAppStore();
Enter fullscreen mode Exit fullscreen mode

That's it. Seriously.


The Migration Journey

Phase-by-Phase Approach

Decision Tree for State Placement


Production Results: The Numbers

Performance Gains

Developer Experience Impact

Metric Before After Change
Time to add feature 4-6 hours 1-2 hours 67% faster
Developer confidence 6.2/10 9.1/10 47% increase
Code review time 45 min avg 20 min avg 56% faster
Onboarding new devs 2 weeks 3 days 80% faster

Cache Performance


Architecture Patterns We Learned

Store Organization

Query Key Strategy


When To Make This Switch

Decision Matrix

Good Fit Scenarios

Scenario Recommendation Why
Simple GraphQL fetching Migrate TanStack Query is lighter, simpler
Building SPAs or dashboards Migrate Better cache control, less overhead
Team struggles with Apollo Migrate Much easier mental model
Need normalized caching Stay Apollo's strength
Heavy GraphQL subscriptions Stay Built-in support

Key Takeaways

The Three Principles

Best Practices Checklist

  • [ ] Separate server state from client state
  • [ ] Use hierarchical query keys
  • [ ] Keep Zustand stores focused and small
  • [ ] Leverage TanStack Query's automatic caching
  • [ ] Use TypeScript for type safety
  • [ ] Set reasonable staleTime values
  • [ ] Enable DevTools during development
  • [ ] Monitor bundle size regularly

Resources & Next Steps

Official Documentation

Community & Support

Further Reading

  • "Goodbye Redux? Meet TanStack Query" - Industry shift analysis
  • "TanStack Start vs Next.js" - Framework comparison
  • "Modern React Patterns 2025" - Current best practices

About GLINR & GLINCKER

GLINR is our AI-powered developer platform offering:

  • Profanity detection with AI enhancement
  • Text summarization via GCP NLP
  • URL shortening and QR generation
  • AI assistant services (upcoming)

GLINCKER is our parent brand building practical AI micro-tools for developers and businesses.


Connect & Follow

Topics I write about:

  • Modern React architecture
  • Full-stack development patterns
  • AI/ML integration strategies
  • Developer productivity
  • Building scalable platforms

Share Your Experience

Have you migrated from Apollo? Using TanStack Query + Zustand in production? Share your story in the comments below.

Found this helpful? Please share with your team and clap if you enjoyed the read.


This article is part of the GLINCKER Engineering Series. More coming on Next.js 15 patterns, Spring Boot 3 architecture, and building AI-powered SaaS platforms on limited resources.


Tags: #React #StateManagement #TanStackQuery #Zustand #WebDevelopment #JavaScript #TypeScript #Architecture #Apollo #GraphQL #NextJS #Frontend #Performance #2025


Published by GDSKS • Lead Architect, Founder at GLINCKER • Building GLINR Platform

Last updated: November 2025

Top comments (0)