Building This Site: A Deep Dive Into My Custom React Portfolio

Welcome to an in-depth look at how I built tomxxi.com. This is personal portfolio website, blog, and professional showcase. This site represents not just a collection of my work, but a demonstration of my skills as a full-stack developer with a passion for creating polished, performant web experiences.
Websites are a relatively new part of my professional repetoire. My previous professional experience has mostly been focused on what I'd consider more 'low level' and practical software development, such as mobile applications, backend services, and desktop software. I am much more comfortable, still, in lower level languages and Win32 programming... However, I wanted to create a site that could serve as a central hub for my portfolio, blog, and contact information, while also showcasing my newly acquired abilities in modern web development.
What makes this project particularly special is that every component, every animation, and every design element was built from scratch. No component libraries, no pre-built templates - just React, TypeScript. Not only was this built to showcase my skills, but it was also a way of personal growth and learning in this brand new frontier of software development for me.
In this post, I'll walk you through the technical architecture, design decisions, and the custom UI library that powers this entire site. Whether you're a fellow developer looking for inspiration or a potential employer wanting to understand what I've been up to, this deep dive will give you insight into how I approach web development and hopefully software development as a whole!
Core Technologies
I have some light experience in PHP and other web technologies from many years ago, but I settled on React + Vite for this project as I know this is a popular stack these days and I feel like it is the direction the industry is travelling towards.
- Vite: Lightning-fast build tool and development server with Hot Module Replacement (HMR). Vite provides instant server start, blazing fast updates, and optimized production builds with code splitting.
- React 19: The latest version of React, leveraging functional components, hooks, and the new concurrent features for optimal performance and user experience.
- TypeScript: Full type safety across the entire codebase. Every component, every prop, every data structure is strongly typed, catching errors at compile time rather than runtime.
- React Router v7: Client-side routing with lazy-loaded pages for optimal bundle sizes. Each page and blog post is code-split and loaded on demand.
- Framer Motion: The only external UI library used - for powerful, production-ready animations and transitions. Every scroll animation, page transition, and interactive element uses Framer Motion's declarative API.
A Fully Custom UI Library
I went with a fully custom UI library for this site because I wanted it to be very personal to me and my sensibilities. While I have used MUI at work, I like the fact that I understand every element of this site inside out. It makes me a better developer and has been a good tutorial in React development.
- Navigation System: Responsive navbar, bottom navigation bar for mobile, and a navigation rail for desktop. Each adapts seamlessly to different screen sizes with smooth transitions.
- Project & Blog Cards: Elevated cards with glass-morphism effects, hover animations, skeleton loading states, and responsive layouts. Each card is optimized for both visual appeal and performance.
- Content Templates: Reusable templates for blog posts and project pages with consistent styling, animations, and metadata handling. These templates ensure every piece of content looks polished.
- Section Components: OverviewSection, MainSection, ListSection, MediaSection, and more - composable building blocks that make content creation intuitive and consistent.
- Interactive Elements: Floating action buttons, external link modals with safety warnings, scroll indicators, profile avatars, and more - all with smooth animations and accessibility features.
- Layout Components: Glass-effect surfaces, gradient borders, animated backgrounds, section dividers with decorative elements, and a comprehensive layout system.
Design System & Styling
The visual identity of this site is built on a carefully crafted design system using TailwindCSS v4 with extensive customization. Rather than using Tailwind out of the box, I extended it with custom CSS variables, theme definitions, and utility classes.
1:root {
2 --kk-gold: #d4af37;
3 --kk-bronze: #a78f5c;
4 --kk-teal: #00ffd5;
5 --kk-rose: #ff2c75;
6
7 /* Dark theme (default) */
8 --background-primary: #0a0a0f;
9 --background-surface: #1a1a2e;
10 --text-primary: #e0ded2;
11}The color palette combines gold accents (#d4af37) with teal and rose highlights. I think this palette is very clear and readable, and shows somewhat my personal preference for the Art Deco design philosophy. The site supports both dark and light themes with smooth transitions, though dark mode is the default to emphasize the visual effects.
Custom utility classes like glass-effect, shimmer, glow-text, andelevated-card provide reusable styling patterns that maintain consistency across components.
Visual Design Features
I see the industry moving away from flat design and more towards depth and motion, again. Obviously iOS 26 is somewhat of an influence, though I didn't want to go full liquid glass. I think Apple's new design philosophy is good but has problems with readability. It is imperative that this content rich site is readable.
- Glass Morphism: Translucent surfaces with backdrop blur effects create depth and modern aesthetics throughout the interface.
- Gradient Effects: Subtle animated gradients in the background, gradient borders on interactive elements, and gradient underlines on section headers.
- Custom Typography: Orbitron for titles (a futuristic, geometric font) and Inter for body text. Carefully tuned font sizes, weights, and line heights for optimal readability.
- Animations Everywhere: Scroll-triggered animations, hover effects, page transitions, shimmer effects, and smooth state changes using Framer Motion.
- Responsive Design: Mobile-first approach with breakpoints for tablet and desktop. Bottom nav on mobile transforms into a navigation rail on larger screens.
Progressive Web App Features
This site isn't just a website - it's a single page Progressive Web App (PWA) that can be installed on any device and works offline. This was implemented using vite-plugin-pwa with a custom service worker strategy.
1VitePWA({
2 registerType: "autoUpdate",
3 strategies: "injectManifest",
4 srcDir: "public",
5 filename: "sw.js",
6 manifest: {
7 name: "Tom Taylor",
8 short_name: "Tom Taylor",
9 description: "Personal website, blog & portfolio",
10 theme_color: "#D4AF37",
11 display: "standalone",
12 }
13})The PWA implementation includes custom icons, splash screens, and a caching strategy that precaches critical assets while using runtime caching for larger files. Users can install the site on their home screen and access it offline with full functionality.
While I obviously do not expect people to actually use this site as an app, I love having it as an opportunity. On the few contractor projects I've taken on in React, I've always tried to make them fully support PWA.
If nothing else, it forces me to think about performance, caching, and offline capabilities in a way that traditional web development does not. I think everyone is designing mobile-first these days, so I want to ensure that this is my philosophy here too.
Architecture & Code Organization
The codebase is organized for maximum maintainability and scalability. Every file has a clear purpose, and the folder structure follows industry best practices:
1src/
2├── components/ # Reusable UI components
3│ ├── ui/ # Base UI elements (buttons, headers, etc.)
4│ ├── blog/ # Blog-specific components
5│ └── projects/ # Project page components
6├── pages/ # Page components (lazy-loaded)
7│ ├── main/ # Main site pages
8│ ├── blog/ # Individual blog posts
9│ └── projects/ # Individual project pages
10├── data/ # Static data & content definitions
11├── styles/ # Global styles & theme
12├── utils/ # Utility functions & animations
13└── hooks/ # Custom React hooksPath aliases (@components, @pages, @data, etc.) make imports clean and maintainable. TypeScript interfaces ensure type safety across all data structures, from blog posts to project metadata.
A common trend in my work is trying to use clean code strategies wherever possible. I have read (and re-read) Clean Code by Robert C. Martin multiple times, and I try to apply those principles wherever possible. This means small, single-responsibility functions and components, clear naming conventions, and avoiding duplication at all costs.
You can see why I would generally prefer lower level, practical application development based on the above.
Key Architectural Decisions
As with any project, it's important to decide on important technical decisions at the outset. I do not like accruing technical debt. Wherever possible, I try to take a data driven approach. It's much easier to maintain a dataset than a spiralling codebase.
- Data-Driven Content: All blog posts and projects are defined in TypeScript data files with metadata, lazy-loaded React components, and helper functions for filtering and sorting.
- Lazy Loading Everywhere: Every page and blog post is lazy-loaded using React.lazy(), ensuring the initial bundle size remains small and subsequent pages load instantly.
- Manual Chunk Splitting: Vite is configured to split vendor dependencies (React, Framer Motion) into separate chunks for optimal caching and parallel loading.
- Component Composition: Rather than building monolithic components, everything is composed of smaller, reusable pieces. This makes the codebase more maintainable and testable.
- Animation System: Centralized animation variants in a utils file ensure consistency across all page transitions and scroll animations.
The Blog System
While I do have experience developing using a traditional CMS, I decided to build a completely custom React-based authoring system. Each blog post is a TypeScript/React component that uses composable section components.
This allows me fine grain control over the layout, styling, and interactivity of each post while maintaining consistency through reusable components.
Of course the tradeoff here is that writing blog posts or project portfolio pieces takes considerably longer and more thought than some simple (but boring) markdown based blog.
1export const blogPosts: BlogPost[] = [
2 {
3 slug: "building-this-site",
4 title: "Building This Site",
5 description: "An in-depth look at how this site was built...",
6 tags: ["React", "TypeScript", "Vite", "Portfolio"],
7 publishedDate: "2025-01-06",
8 readingTime: 15,
9 featured: true,
10 component: lazy(() => import("@pages/blog/BuildingThisSite")),
11 }
12];This approach provides several advantages over traditional blogging systems:
- Full TypeScript support - I will always opt for static typing wherever possible. I hate JavaScript
- Reusable components -
OverviewSection,MainSection,ListSection,CodeBlockcreate consistency across the app - Interactive content - Can embed any React component, create interactive demos, or use custom layouts
- Code splitting - Each post is lazy-loaded, keeping the main bundle small
- SEO friendly - React Helmet handles meta tags, Open Graph data, and structured data for each post
Performance & Optimization
Performance is always a top priority for me. In my day job I am a low level software developer after all. I know that the React/NodeJS stack is not exactly known for its rapidity, but I have maintained constant best practises throughout to ensure it is as optimal as possible, while retaining my style goals.
- Code Splitting: Every page, blog post, and project page is lazy-loaded. The initial bundle only includes the home page and shared layout components.
- Image Optimization: All images are WebP format with skeleton loading states. Images lazy-load as users scroll and include proper dimensions to prevent layout shift.
- Asset Caching: Service worker precaches critical assets with network-first strategy for dynamic content. Content hashes on all assets ensure cache busting.
- Tree Shaking: Vite automatically removes unused code. Only the Framer Motion features we actually use are included in the bundle.
- Bundle Analysis: Rollup plugin visualizer generates bundle statistics showing exactly what's in each chunk and where size optimizations can be made. The result is an initial page load under 100KB (gzipped) with Lighthouse scores consistently hitting 90+ across all metrics.
Development Experience
Beyond the user-facing features, this project showcases how I set up the most efficient development environments I can manage.
My IDE on projects like this is almost always Visual Studio Code. I love the extensions and the complete control I have over build scripts, linting, and formatting. I have a very customized setup that I use for all my React projects.
- Hot Module Replacement (HMR) - Changes appear instantly without full page reloads
- TypeScript strict mode - Maximum type safety catches bugs before they happen
- Path aliases - Clean imports with
@components,@pages, etc. - ESLint configuration - Automatic code quality checks and formatting
- Build optimization - Production builds with minification, compression, and tree shaking
What This Project Demonstrates
- System Design: Architecting a scalable, maintainable codebase with clear separation of concerns, reusable components, and efficient code organization.
- UI/UX Development: Building polished, animated interfaces with attention to detail, smooth transitions, and thoughtful interaction design without relying on third-party libraries.
- Performance Engineering: Implementing code splitting, lazy loading, caching strategies, and bundle optimization to create fast, efficient web applications.
- Modern Web Technologies: Leveraging the latest features of React, TypeScript, Vite, and PWA APIs to build production-ready applications with excellent developer experience.
- CSS Mastery: Creating sophisticated visual effects (glass morphism, gradients, animations) using modern CSS features, custom properties, and Tailwind utilities.
- Full-Stack Thinking: Considering the entire user journey from initial load to offline functionality, SEO optimization, and cross-device compatibility.
Conclusion
While not my primary area of expertise, I really enjoy my time spent in React... And Typescript in general. This project is no exception.
Building tomxxi.com from the ground up has been an incredible learning experience that has expanded my skill set into modern web development and made me a better developer in general.
As previously mentioned, I have taken on a few contractor projects in React for clients, and I always try to make them as close to this level of quality as possible. I think that is important, even for small projects. I do not like to half-heart any project and I feel I am happy with this site at this point.
Feel free to explore the rest of the site, check out my other projects, or reach out via the contact page if you'd like to discuss web development, React, or anything else tech-related!
