Development

How We Built This In 30 Days

How three experienced developers built a modern marketing website with 200+ static pages in 30 days of work time using Next.js 15, Tailwind CSS v4, Claude Code, and Cursor IDE—without compromising human ownership of every line of code.

Eric Wagoner, Sharni Zaugg, John Bowser
11/17/2025
10 min read

When we set out to rebuild Infinity Interactive's website, we knew we needed to move fast. But we also knew we needed to tell a different story.

Our legacy site reflected a time when technical people brought us in to help them do technical work. But our business had evolved. In recent years, most of our clients have been small business owners and directors at larger companies: people who need technical problems solved but don't want to manage the technical details themselves. We needed to show them who we are, how we work, and how we can seamlessly take technical headaches off their hands.

As experienced developers who build software day in and day out, we already use the latest generation of AI tools in our daily work. For this project, we leveraged that experience and Claude Code as our assistant to deliver results quickly without compromising quality.

The result? A fully static Next.js website with over 200 pages, a complete blog migration, and a modern design system—all built in about 30 days of actual work time (spread over 8 calendar weeks while we handled client projects). Here's how we did it.

The Starting Line: September 22, 2025

Our journey began with a single commit: "Initial commit." We started with a proof of concept (a React SPA with React Router) to quickly validate our design ideas and content structure. Like most real-world projects, we knew we'd evolve the architecture as we learned what we actually needed.

We also made another key decision: we would use AI-assisted development tools throughout the project. Specifically, Claude Code and the Cursor IDE as our primary assistants. Not to write code for us, but to help us move faster on the decisions we made and the code we wrote.

Setting Up for Success

One of our first moves was integrating Claude Code directly into our GitHub workflow. We added two GitHub Actions:

  1. Claude PR Assistant - Automated PR descriptions and summaries
  2. Claude Code Review - Automated code reviews on pull requests

This gave us an additional layer of review, catching potential issues before human review. But make no mistake—we reviewed every line of code ourselves and made all the architectural decisions.

Week 1-2: Foundation and Design

The first two weeks focused on establishing our architecture and design language.

Modern Design System Implementation

On October 8, Eric tackled one of the biggest early challenges: implementing a comprehensive brand design system. This wasn't just about making things look pretty. It was about creating a cohesive visual language that would scale across dozens of pages.

To help organize and maintain design consistency, Eric used a specialized Claude sub-agent he'd written specifically for design system work. This custom agent helped coordinate design decisions across the project—but that's a story for another blog post.

typescript
// Our design system introduced: - Bento grid layouts for content organization - Glassmorphism effects for depth and visual interest - Consistent color palette with gradient accents - Responsive typography system - Reusable component patterns

The design featured bold gradients, modern card layouts, and smooth animations—a far cry from our previous site. But we also made sure it was functional, with clear navigation and intuitive user flows.

Architecture Cleanup: Phases 1-3

Sharni led a massive refactoring effort that transformed our codebase from a monolithic structure into a clean, modular architecture:

  • Phase 1: Separated data from presentation logic
  • Phase 2: Extracted the HomePage into modular section components
  • Phase 3: Restructured the content layer for maintainability

This refactoring created a foundation that would support rapid feature development for the rest of the project.

Week 3-4: Content Migration

October 17-20 marked a major milestone: migrating our existing content.

Blog Posts and Case Studies

We had years of blog posts on our old site: nearly 100 posts covering everything from technical deep-dives to industry insights. Not all remained relevant, but we migrated about 70 posts that still had value for our audience and showcased our expertise.

John built a flexible Markdown-based blog system that could handle:

  • Code syntax highlighting with react-syntax-highlighter
  • Embedded CodePen demos (for our Archer animation post)
  • Custom CSS and JavaScript injection for complex posts
  • Responsive images with proper aspect ratios

The most challenging post? Will's "Archer Animation" article, which included complex SVG animations and required custom component injection. But the system we built was flexible enough to handle it.

The Great Next.js Migration (October 21)

After proving our design concepts and content structure with the React Router proof of concept, it was time to build for production. We needed static site generation for optimal SEO and performance. A marketing site doesn't need client-side routing and server costs.

Eric led an intense one-day migration from React Router to Next.js 15 with static export. Looking at the commit history for October 21, you can see the intensity:

16:23 - Initialize Next.js migration with configuration files 16:29 - Create Next.js layouts and initial pages 16:37 - Successfully build Next.js with static HTML generation 16:54 - Migrate complete HomePage with all sections 17:59 - Complete migration with blog posts and case studies 18:02 - Remove old React Router and Vite files

In less than 2 hours, Eric transformed the entire application architecture. This wasn't just a framework swap. We completely changed how the site generated, routed, and deployed.

This is where having Claude Code as an assistant proved valuable. Rather than manually converting dozens of components from React Router's Link and useRouter to Next.js equivalents one by one, Eric used Claude Code to help:

  1. Identify all the routing patterns across components
  2. Apply systematic updates to imports and component usage
  3. Verify the changes were consistent

But Eric designed the migration strategy, reviewed every change, and ensured nothing broke in the process. The tool accelerated the mechanical work; the human made the decisions and owned the outcome.

Week 5-6: Polish and Refinement

Tailwind CSS v4 Migration

That same evening (October 21), we tackled another major upgrade: migrating from Tailwind CDN to Tailwind CSS v4 with build-time compilation.

The new approach used CSS-based configuration with the @theme directive in globals.css:

css
@theme { --color-infinity-blue: #0066cc; --color-teal-500: #14b8a6; /* Custom shadows, animations, and more... */ }

This gave us better performance (no CDN dependency), more flexibility (custom design tokens), and faster build times.

The Little Things That Matter

October saw a flurry of UX improvements:

  • Testimonials carousel with real client reviews (PR #58)
  • Rotating buzzwords in the hero section: "Best Practice," "technology," "AI," and more (PR #63)
  • Client logo carousel featuring 30+ client logos (PR #69)
  • Form integration with Formspree for contact submissions (PR #66)
  • FiTT section for our staff augmentation service with a beautiful progressive timeline (PR #62)

Each improvement was small, but together they transformed the site from functional to delightful.

Week 7-8: Blog Overhaul and Tooling

Blog System 2.0

In early November, John completely overhauled the blog system (PR #87, #106):

Before:

typescript
// Loosely typed, inconsistent properties export const myPost = { id: "1", author: "John", date: "2025-11-01", type: "article", gradient: "purple" // ... many more fields };

After:

typescript
import { BlogPost } from "@/types/types"; export const myPost: BlogPost = { slug: "my-post", authors: ["John Bowser"], publishDate: new Date("2025-11-01"), category: "Development", tags: ["Next.js", "React"], color: "blue", content // Strongly typed, validated at build time };

This introduced several improvements:

  • Strong TypeScript typing for all blog metadata
  • Constants for categories and tags (no more typos)
  • Support for injected components and custom CSS
  • A BlogPost type that enforces consistency

We even added an npm script to bootstrap new blog posts:

bash
npm run blog-post "My New Post Title"

This generates the folder structure, template files, and updates the index—saving precious time.

Code Quality Tooling

John also established comprehensive code quality tooling (PR #96, #113, #126):

  • ESLint 9+ with flat config and TypeScript rules
  • Prettier 3.6+ for consistent formatting
  • Husky with pre-commit hooks (lint + format check)
  • Pre-push hooks that run the full build to catch errors
  • VSCode settings for consistent editor behavior

Now, broken code can't even get committed, let alone pushed. The build runs before every push, ensuring we never break production.

How We Used AI Tools as Our Assistants

As seasoned developers, we've learned that AI tools are most effective when they amplify human expertise rather than replace it. Here's how we used Claude Code and Cursor IDE throughout this project, and what we didn't use them for:

What We Owned (100% Human)

  • All architectural decisions: Next.js vs. other frameworks, static vs. SSR, content structure
  • Design system: Visual language, component patterns, UX flows
  • Code review and quality: We reviewed every line, every PR, every change
  • Problem-solving: When things broke (and they did), we debugged and fixed them
  • Business logic: How the site works, what it does, how content is organized

How Claude Code Helped Us Move Faster

1. Mechanical Refactoring

When we needed to update 50+ components to use a new routing pattern, we didn't manually edit each file. We used Claude Code to apply the systematic changes while we focused on the strategy and verification. The pattern was ours; the tool just executed it consistently.

2. Boilerplate Generation

Writing TypeScript interfaces, prop types, and repetitive component structures? Claude Code handled the mechanical parts while we focused on the logic and behavior that actually mattered.

3. Documentation Assistance

We wrote the documentation, but Claude Code helped format it, catch inconsistencies, and ensure completeness. The knowledge is ours; the tool helped us express it clearly.

4. Code Review Augmentation

Our GitHub Actions gave us an extra set of eyes on PRs, catching potential TypeScript errors, accessibility issues, or security concerns. But we still did thorough human reviews on every change.

5. Content Migration Support

Converting nearly 100 blog posts from one format to another (and curating down to about 70 relevant posts) involved a lot of pattern matching and formatting. Claude Code and Cursor helped with the mechanical parts while we handled the content decisions and quality checks.

The Human-First Principle

Every line of code in this project was written, reviewed, and owned by humans. Claude Code and Cursor accelerated our work, but they didn't make our decisions or write our software. We're experienced developers using powerful tools, not fresh developers relying on AI to do our thinking for us.

This distinction matters. Our clients hire us for our expertise, judgment, and ability to solve complex problems. AI tools like Claude Code and Cursor make us more efficient, but they don't replace the years of experience we bring to every project.

The Numbers

By the numbers, here's what we delivered:

  • 200+ static pages generated at build time
  • ~70 blog posts migrated and reformatted from nearly 100 original posts
  • 5 case studies with full detail views
  • 6 service pages with dynamic content
  • 129 redirect pages preserving old URLs for SEO
  • 130+ commits across the team
  • 130+ pull requests reviewed and merged

All built by a team of 3 developers in about 30 days of work time.

Technical Highlights

Static Site Generation

Every page is pre-rendered at build time using Next.js's generateStaticParams():

typescript
export async function generateStaticParams() { return blogPostsSortedByDate.map((post) => ({ slug: post.slug })); }

This means:

  • Zero server costs for dynamic rendering
  • Instant page loads: everything's already HTML
  • Perfect SEO: search engines see full HTML immediately
  • Edge deployment: can serve from CDN anywhere

Developer Experience

We optimized for maintainability:

typescript
// Adding a new blog post is as simple as: npm run blog-post "My New Post Title" // Then edit two files: // 1. index.ts (metadata) // 2. content.md (actual content)

The build fails if you forget required fields or use invalid categories/tags. TypeScript catches errors before they reach production.

SEO and Performance

We implemented:

  • Open Graph tags for social sharing
  • Twitter Card metadata for rich previews
  • JSON-LD structured data for search engines
  • Proper semantic HTML throughout
  • Fast load times thanks to static generation

Our Methodologies, Applied to Our Own Project

1. Proof of Concept, Then Commit

Starting with a React Router proof of concept let us validate our design and content structure quickly. When it was time to commit to a production architecture, we made an informed decision (Next.js with static generation) based on what we'd learned. The one-day migration proved that evolving your architecture isn't necessarily expensive if you plan for it.

2. Invest in Tooling Early

The time John spent setting up ESLint, Prettier, and Husky paid dividends. It's much easier to maintain code quality from day one than to retrofit it later.

3. Type Safety is Worth It

TypeScript strict mode catches potential bugs before they reach production. The upfront cost of typing everything properly is far less than debugging runtime errors after the fact.

4. AI as an Accelerator

Used correctly, AI tools like Claude Code can significantly accelerate development without compromising quality. The key is knowing when to use them for mechanical tasks and when to rely on human expertise for decisions and problem-solving.

5. Small, Focused PRs

Most of our PRs were focused on a single feature or fix. This made reviews faster and reduced merge conflicts. It also meant we could ship improvements continuously.

What's Next?

The site is live, but we're not done. We're already planning:

  • Blog post series sharing our technical expertise
  • Additional case studies showcasing client work
  • Continuous content updates as we grow
  • A Cohesive Social Media Presence to amplify our reach

Our Approach to AI-Assisted Development

If you're considering using AI tools in your development workflow, here's our advice:

  1. Use AI for acceleration, not abdication: Let it handle mechanical tasks while you focus on architecture and problem-solving
  2. Review everything: Never merge code you haven't understood and verified yourself
  3. Own your decisions: The AI can suggest; you decide. Always.
  4. Invest in your expertise first: AI tools are multipliers. If you don't have strong fundamentals, the tool won't help you.
  5. Set clear boundaries: Know what you'll use AI for and what requires pure human judgment

The combination of experienced developers and smart tooling is powerful. But the emphasis is on "experienced developers" first, "smart tooling" second. We'll be expanding on our human-first approach to using AI tools here in the coming weeks!


The site you're reading this on? Built in 30 days of work time by 3 experienced developers juggling client projects. No AI abdication, no cutting corners—just seasoned professionals who know how to leverage the right tools at the right time to deliver quality quickly.

Want to build something extraordinary with a team that owns every line of code? Let's talk →

AgileAI

Ready to Start Your Project?

Let's discuss how we can help bring your ideas to life with thoughtful design and robust development.