Building a Production-Ready Portfolio: Phase-2 — Frontend Bootstrapping & Architecture Setup
Source: Dev.to
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.”
Goals
- 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 it is 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 developer experience for React projects
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 organized the frontend into a dedicated frontend/ folder.
Benefits
- Frontend and backend evolve independently
- CI pipelines stay clean
- Deployment targets are clear
- Ownership boundaries are respected
From a product and engineering standpoint, this mirrors 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 a consistent code style
- Reduce review friction
- Prevent formatting debates
- Keep PRs clean and readable
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
- 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
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.
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
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
Contains reusable, layout‑agnostic building blocks 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
components/layout
Layout components define structure, not content.
Examples
NavBarFooterLayouts
These components:
- Wrap pages
- Manage shared UI
- Define skeleton and spacing
components/sections
Sections represent domain‑specific UI.
Examples
HeroAboutProjectsOpenSource
These are:
- Content‑aware
- Page‑specific
- Allowed to evolve independently
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
When APIs evolve, only hooks change — not the 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
Benefits:
- avoids tight coupling
- supports mocking
- makes CI tests easier later
Styles & Assets: Keeping Things Organized 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:
- Frontend bootstrapped with modern tooling
- Scalable folder structure in place
- Routing planned (not rushed)
- Code‑quality tools configured
- UI, logic, and data clearly separated
- 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 prioritized
- 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.