With infrastructure ready and requirements clearly defined, it was finally time to write code. However, instead of jumping straight into UI components, this phase focused on establishing a frontend foundation that could scale, evolve, and remain maintainable.
🔗 Project Repository:
https://github.com/imsushant12/sushantgaurav-portfolio
Why Frontend Setup Deserves Its Own Phase
After completing:
- Phase-0: Infrastructure & workflows
- Phase-1: Requirement gathering & PRD
I had something most side projects don’t:
- clarity of scope
- clear user flow
- defined responsibilities
So when Phase-2 started, the goal was not to “build UI”.
The goal was to:
- establish frontend architecture
- lock tooling decisions early
- enforce consistency
- reduce future refactoring
- make the codebase contributor-friendly
This phase represents Day-3 of the project, but again — it’s treated as a proper engineering phase, not a daily log.
Phase-2 Objective
The objectives of this phase were intentionally limited:
- Bootstrap the frontend using modern tooling
- Set up folder structure before feature development
- Configure styling, linting, and formatting
- Plan routing without implementing full pages
- Prepare the app to scale without rewrites
No UI polish yet.
No feature completion yet.
Only foundations.
Step 1: Bootstrapping the React App with Vite
For the frontend, I chose Vite + React instead of older bundlers.
Why Vite?
- extremely fast dev server
- modern ESM-based tooling
- minimal configuration
- excellent DX for React projects
The intention was simple:
Start fast, stay fast, and avoid unnecessary complexity.
This decision also aligns well with CI/CD and future build pipelines.
Step 2: Setting Up the Frontend Workspace
Instead of letting the default structure grow organically, I immediately organised the frontend into a dedicated frontend/ folder.
This separation ensures:
- frontend and backend evolve independently
- CI pipelines stay clean
- deployment targets are clear
- ownership boundaries are respected
From a product and engineering standpoint, this aligns with how real teams structure their repositories.
Step 3: Installing Core Dependencies (Intentionally, Not Randomly)
Before writing components, I installed the minimum required tooling to support long-term quality:
Styling
-
Tailwind CSS
Chosen for:- consistency
- rapid iteration
- utility-first discipline
- easier design refactoring later
Routing
-
React Router DOM
Installed early to:- plan navigation
- align with the user journey defined in Phase-1
- avoid routing rewrites later
Code Quality
Configured early to:
- enforce consistent code style
- reduce review friction
- prevent formatting debates
- keep PRs clean and readable
This wasn’t about “adding tools” — it was about setting expectations for how code should look and behave.
Step 4: Planning Routing Before Building Pages
Instead of creating pages first and wiring routes later, I reversed the process.
Why?
- Routing defines the user journey
- Pages should follow navigation, not dictate it
- This prevents unnecessary rewrites
I mapped routes based on:
- the PRD
- the user flow diagram from Phase-1
- the portfolio sections identified earlier
At this stage:
- routes were planned
- structure was prepared
- actual content was intentionally minimal
This approach keeps development aligned with product intent.
Step 5: Designing the Frontend Folder Structure (Before Writing Features)
One of the most important decisions in this phase was frontend architecture.
Instead of dumping everything into components/, the structure was intentionally layered.
Here’s the high-level view:
src/
├── components
├── pages
├── hooks
├── data
├── services
├── styles
├── contexts
This structure answers key questions early:
- Where does UI live?
- Where does logic live?
- Where does data come from?
- Where do API calls belong?
It also makes the codebase easier to understand for:
- future contributors
- reviewers
- your future self
Why This Phase Matters (Even Though Nothing “Visible” Exists Yet)
At this point:
- there is no polished UI
- no animations
- no finished pages
But the frontend is already:
- scalable
- predictable
- structured
- maintainable
This is where many projects quietly fail — by skipping structure and paying the cost later.
Component Architecture: Thinking Beyond “Just Components”
One of the biggest mistakes in frontend projects is treating every file as just another component.
Instead, I classified components based on responsibility.
components/common
This folder contains:
- reusable building blocks
- layout-agnostic components
- components with no business logic
Examples:
Section.jsxSectionHeader.jsx
These components:
- don’t know where they are used
- don’t depend on routing
- are easy to reuse across pages
This separation reduces duplication and improves consistency.
components/layout
Layout components define structure, not content.
Examples:
NavBarFooterLayouts
These components:
- wrap pages
- manage shared UI
- define skeleton and spacing
By isolating layout logic, page components stay clean and focused.
components/sections
Sections represent domain-specific UI.
Examples:
HeroAboutProjectsOpenSource
These are:
- content-aware
- page-specific
- allowed to evolve independently
This mirrors how real design systems are structured.
Pages vs Sections (A Deliberate Distinction)
A common anti-pattern is mixing routing and UI logic.
To avoid that, I made a clear distinction:
pages/
- route-level components
- map directly to URLs
- assemble sections
- minimal logic
sections/
- reusable across pages
- represent logical content blocks
- unaware of routing
This ensures:
- routes remain thin
- UI stays composable
- refactoring becomes easier
It also allows:
- page restructuring without rewriting UI
- consistent layout reuse
Hooks: Separating Logic From UI
Instead of embedding logic directly inside components, I introduced a hooks/ layer early.
Purpose:
- isolate data-fetching logic
- encapsulate side effects
- improve testability
- reduce component complexity
Examples:
useProjectsuseAchievementsuseAbout
This keeps components:
- declarative
- easier to read
- easier to debug
And later, when APIs evolve, only hooks change — not UI.
Data Layer: Decoupling UI From Content
At this stage, most content lives in JSON files inside data/.
Why?
- content changes more frequently than UI
- enables rapid iteration
- simulates API-driven development
- simplifies early testing
Files like:
projects.jsonexperiences.jsonhero.json
act as a temporary backend.
When real APIs are wired later, the transition becomes smooth.
Services Layer: Preparing for Backend Integration
Even though the backend is not yet fully implemented, I created a services/ layer.
This layer:
- centralizes API calls
- isolates HTTP logic
- prevents API usage from leaking into components
Example:
api.js
This decision:
- avoids tight coupling
- supports mocking
- makes CI tests easier later
Styles & Assets: Keeping Things Organised Early
Styles
All global styles were placed under:
styles/
├── globals.css
├── animations.css
This avoids:
- scattered CSS
- inline chaos
- inconsistent animations
Assets
Assets were grouped by domain:
- hero
- about
- projects
- logos
This improves:
- readability
- asset reuse
- maintainability
ESLint & Prettier: Enforcing Discipline Early
Linting and formatting were configured before writing features.
This ensures:
- consistent style
- predictable diffs
- easier PR reviews
- fewer subjective debates
As a lead or reviewer, this saves enormous time later.
What Phase-2 Achieved
By the end of this phase:
[x] Frontend bootstrapped with modern tooling
[x] Scalable folder structure in place
[x] Routing planned (not rushed)
[x] Code quality tools configured
[x] UI, logic, and data clearly separated
[x] Backend integration prepared
Still no “flashy UI” — but a strong, real-world frontend foundation.
Why This Phase Matters (Especially for Portfolios)
Most portfolios showcase what was built.
This phase showcases:
- how decisions were made
- how architecture was planned
- how maintainability was prioritised
- how real teams think
This is what differentiates:
“I built a portfolio”
from
“I engineered a product.”
What’s Next?
Phase-3 will focus on backend setup and API foundations
Now that the frontend can consume APIs cleanly, it’s time to build them properly.

Top comments (0)