Dev Diary: Building godegit.dev - Phase 1: Foundation & Brand System
Follow our journey building the godegit website from the ground up. In this first phase, we establish the brand foundation, configure our tech stack, and set up the development environment with TypeScript, Tailwind CSS, and Nuxt 3.


Setting up our brand color system in Tailwind CSS configuration
The Foundation: Where Great Websites Begin
Welcome to our development diary series documenting the creation of godegit.dev - the marketing website and documentation hub for our fast Git repository download tool. As developers who value transparency and sharing knowledge, we want to take you behind the scenes of building a modern, performant, and brand-compliant website from scratch.
Why Document the Process?
Building godegit taught us that developers appreciate tools that "just work" without unnecessary complexity. We wanted to apply the same philosophy to our website: clean, fast, and purpose-built. But unlike our CLI tool, a website needs to communicate brand values, provide comprehensive documentation, and create an engaging user experience.
This dev diary series will cover our complete journey through 10 phases and 67 specific tasks, following Test-Driven Development (TDD) principles and maintaining strict brand compliance throughout.
Phase 1: Project Setup & Brand Foundation
The Tech Stack Decision
After evaluating several options, we chose a modern, performance-focused stack:
- Nuxt 3: For its excellent developer experience, automatic optimization, and powerful content management capabilities
- TypeScript: Essential for maintainable code in a growing project
- Tailwind CSS: Perfect for implementing our precise brand design system
- Vitest + Playwright: Comprehensive testing coverage from unit to end-to-end
- @nuxt/content: For our documentation and blog content management
Establishing the Brand Identity
Our brand needed to reflect the core values of godegit: efficiency, simplicity, and developer focus. This translated into specific design decisions:
Color Palette:
:root {
--brand-dark: #1a1a1a; /* Primary text, professional */
--brand-light: #f7f7f7; /* Clean backgrounds */
--brand-accent: #2196f3; /* Action items, links */
--brand-muted: #757575; /* Secondary text */
}
Typography System:
- Headings: Inter/Lato for clean, modern hierarchy
- Body Text: Serif fonts for improved readability in long-form content
- Code: SF Mono/Consolas for technical content
Design Principles:
- Content-first: Information architecture drives visual design
- Minimalist: Every element serves a purpose
- Performance-conscious: No visual flourishes at the expense of speed
The Development Environment Setup
We started with a clean Nuxt 3 installation and immediately configured our development standards:
# Project initialization
npx nuxi@latest init godegit-site
cd godegit-site
# Essential dependencies
pnpm add -D @nuxtjs/tailwindcss @nuxt/content @nuxt/image
pnpm add -D typescript @typescript-eslint/parser eslint prettier
pnpm add -D vitest @vitejs/plugin-vue @vue/test-utils
pnpm add -D playwright @playwright/test
Tailwind Configuration: The Brand System in Code
Our Tailwind configuration became the single source of truth for our brand system:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: {
dark: '#1A1A1A',
light: '#F7F7F7',
accent: '#2196F3',
muted: '#757575',
},
},
fontFamily: {
heading: ['Inter', 'system-ui', 'sans-serif'],
sans: ['Inter', 'system-ui', 'sans-serif'],
serif: ['Georgia', 'Times New Roman', 'serif'],
mono: ['SF Mono', 'Consolas', 'monospace'],
},
typography: {
DEFAULT: {
css: {
maxWidth: 'none',
color: '#1A1A1A',
// ... brand-specific prose styles
},
},
},
},
},
}
TypeScript Configuration: Strict by Design
We enabled strict TypeScript checking from day one to catch potential issues early:
{
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}
ESLint and Prettier: Consistency Automation
Code consistency isn't just about style—it reflects our commitment to quality:
// eslint.config.js (ESLint 9+ flat config)
export default [
...withNuxt(),
{
rules: {
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'prefer-const': 'error',
},
},
]
Project Structure: Organized for Growth
We established a clear directory structure that would scale with our needs:
├── assets/css/ # Brand styles and utilities
├── components/
│ ├── Content/ # Documentation components
│ └── Marketing/ # Landing page components
├── content/
│ ├── blog/ # Blog posts
│ ├── docs/ # Documentation
│ └── changelog/ # Release notes
├── layouts/ # Page layouts
├── pages/ # Route components
├── public/ # Static assets
├── tests/
│ ├── e2e/ # Playwright tests
│ └── unit/ # Vitest tests
└── types/ # TypeScript definitions
Challenges and Lessons Learned
Challenge 1: Balancing Brand Consistency with Flexibility
Problem: How do you create a rigid brand system that still allows for creative component design?
Solution: We used Tailwind's component layer to create brand-compliant building blocks:
@layer components {
.btn-primary {
@apply bg-brand-accent focus:ring-brand-accent rounded-md px-4 py-2 font-medium text-white transition-all duration-200 hover:bg-blue-600 focus:outline-none focus:ring-2;
}
}
Challenge 2: TypeScript Configuration Complexity
Problem: Nuxt 3's auto-generated TypeScript configuration conflicted with our strict settings.
Solution: We learned to extend Nuxt's base configuration rather than override it, allowing us to maintain strict typing while preserving framework features.
Challenge 3: Performance vs. Developer Experience
Problem: Some development tools (like comprehensive linting) slow down the development server.
Solution: We configured different environments for development and CI, optimizing each for its specific needs.
What's Next: Phase 2 - Test-Driven Development
In our next dev diary entry, we'll dive into our TDD approach, showing how we wrote comprehensive tests before implementing any components. You'll see how failing tests guided our implementation and ensured we built exactly what we intended.
Coming up in Phase 2:
- Setting up Playwright for end-to-end testing
- Writing unit tests with Vitest and Vue Test Utils
- Creating failing tests for brand compliance
- Performance and accessibility test implementation
Key Takeaways from Phase 1
- Invest in Foundation: Time spent on proper configuration pays dividends throughout development
- Brand as Code: Translate design decisions into configuration files for consistency
- TypeScript from Day One: Strict typing catches issues before they become problems
- Tool Integration: Modern tools work best when properly configured together
The foundation phase might not be the most exciting part of development, but it's arguably the most important. Every subsequent decision builds on these early choices, making this investment in setup and standards crucial for long-term success.
Follow our development journey in the next post where we'll explore our Test-Driven Development approach and show you how to write tests that actually guide implementation.
Repository: github.com/godegit/godegit-siteLive Site: godegit.dev

