This application is architected as a pure Single Page Application (SPA) following Web WhatsApp principles. It is NOT a website or portfolio site—it's a long-lived web application that behaves like a desktop app.
The AppShell component mounts once and never remounts for the entire session:
<AppShell>
<ThemeProvider /> ← Never remounts
<Navbar /> ← Never remounts
<MainView /> ← ONLY dynamic region
<Footer /> ← Never remounts
<ScrollToTop /> ← Never remounts
</AppShell>
Critical: All global systems (WebGL, Three.js, Babylon.js, theme providers) persist in the shell.
Navigation is state-driven, not route-driven:
useAppStore(Zustand) manages all navigation state- UI actions mutate state
- State changes drive view rendering
- URLs (if present) are derived side-effects, not authoritative
Mental Model: "State drives rendering, not routes."
Views are state-rendered surfaces:
src/
├── app/
│ ├── AppShell.tsx ← Persistent shell
│ ├── MainView.tsx ← State-driven view switcher
│ └── store.ts ← Global state (Zustand)
├── views/
│ ├── HomeView.tsx ← State-rendered surface
│ └── ThoughtsView.tsx ← State-rendered surface
Views switch via state:
switch (activeView) {
case 'HOME': return <HomeView />;
case 'THOUGHTS': return <ThoughtsView />;
}const { setView } = useAppStore();
<button onClick={() => setView('THOUGHTS')}>
My Thoughts
</button>No URL dependency. No routing library. Pure state mutation.
Page refresh is treated as:
- App restart
- Session rehydration
- State recovery
On load:
- Restore last active view (from localStorage)
- Restore UI preferences
- Restore scroll context (if applicable)
Code with lifecycle phases in mind:
- Boot: App initialization, state restoration
- Hydration: WebGL/Three.js scene initialization
- Idle: App running, no user interaction
- Interaction: User actions mutate state
- Background: App still running, no active view
- Recovery: Error handling, state restoration
Avoid page lifecycle thinking entirely.
src/
├── app/ ← Application core
│ ├── AppShell.tsx ← Persistent shell (mounts once)
│ ├── MainView.tsx ← State-driven view switcher
│ └── store.ts ← Global state (Zustand)
├── views/ ← State-rendered surfaces
│ ├── HomeView.tsx
│ └── ThoughtsView.tsx
├── components/ ← Reusable components
│ ├── Navbar.tsx ← State-based navigation
│ ├── ThreeGlobe.tsx ← Persistent WebGL scene
│ ├── BabylonScene.tsx ← Persistent 3D scenes
│ └── ...
├── data/ ← Static data
│ └── thoughts.ts ← Blog/thoughts content
└── main.tsx ← Entry point (renders AppShell)
// Store defines views
type AppView = 'HOME' | 'THOUGHTS';
// Actions mutate state
setView('THOUGHTS'); // ← This drives rendering
// MainView renders based on state
switch (activeView) {
case 'THOUGHTS': return <ThoughtsView />;
}- Uses
useAppStorefor navigation state - Button clicks call
setView(view) - Section scrolling handled via
querySelectorandscrollTo - No React Router
- No Link components
- No route definitions
Views are lazy-loaded with React.lazy:
const HomeView = lazy(() => import('../views/HomeView'));
const ThoughtsView = lazy(() => import('../views/ThoughtsView'));Wrapped in Suspense for smooth loading transitions.
interface AppState {
activeView: AppView;
setView: (view: AppView) => void;
isMobileMenuOpen: boolean;
setMobileMenuOpen: (open: boolean) => void;
restoreFromSession: () => void;
}- State persisted to
localStoragevia Zustand middleware activeViewautomatically restored on page load- No manual hydration needed
- Lazy Loading: Views are lazy-loaded with React.lazy
- Persistent Systems: WebGL/Three.js scenes initialize once and persist
- No Remounts: Global systems never remount
- State Persistence: Navigation state persists in localStorage
- Smooth Transitions: View switching is instant (no page reloads)
- Code Splitting: Automatic chunk optimization via Vite
- Mobile Optimization: Reduced animation intensity on mobile devices
❌ NO page-based architecture
❌ NO route-driven component trees
❌ NO remounting global systems
❌ NO anchor tag navigation
❌ NO full reloads except true crashes
❌ NO "React Router as app brain"
✅ YES state-driven navigation
✅ YES persistent AppShell
✅ YES views as state-rendered surfaces
✅ YES state restoration on refresh
✅ YES application lifecycle thinking
- ✅ AppShell mounts exactly once
- ✅ Babylon/Three scenes never reinitialize on navigation
- ✅ Navigation feels instant and continuous
- ✅ Refresh restores previous state
- ✅ No page flashes, reloads, or resets
- ✅ App behaves like an Electron app inside the browser
- ✅ Views lazy-loaded for optimal performance
- ✅ Mobile animations optimized for better UX
const AppShell: React.FC = () => {
return (
<ThemeProvider>
<div className="min-h-screen bg-background text-foreground">
<Navbar />
<main className="flex-grow">
<MainView />
</main>
<Footer />
<ScrollToTop />
</div>
</ThemeProvider>
);
};const MainView: React.FC = () => {
const { activeView } = useAppStore();
switch (activeView) {
case 'HOME':
return (
<Suspense fallback={<LoadingFallback />}>
<HomeView />
</Suspense>
);
case 'THOUGHTS':
return (
<Suspense fallback={<LoadingFallback />}>
<ThoughtsView />
</Suspense>
);
default:
return <HomeView />;
}
};export const useAppStore = create<AppState>()(
persist(
(set) => ({
activeView: 'HOME',
setView: (view: AppView) => {
set({ activeView: view, isMobileMenuOpen: false });
},
// ... other state
}),
{
name: 'portfolio-app-state',
storage: createJSONStorage(() => localStorage),
partialize: (state) => ({ activeView: state.activeView }),
}
)
);"This is Web WhatsApp running in a browser tab — not a website."
Code accordingly.