A robust, modular portfolio website built with vanilla JavaScript, following modern component-based architecture principles similar to React/Vue, but without any frameworks.
yograj/
βββ index.html # Main HTML entry point
βββ style.css # Main stylesheet (imports all CSS modules)
βββ app.js # Legacy app.js (kept for reference)
β
βββ components/ # HTML Component Templates
β βββ Header.html
β βββ Hero.html
β βββ About.html
β βββ Experience.html
β βββ Projects.html
β βββ Skills.html
β
βββ js/ # JavaScript Modules
β βββ app.js # Main application entry point
β β
β βββ core/ # Core framework files
β β βββ Component.js # Component base class & template engine
β β βββ Router.js # Router for navigation
β β
β βββ components/ # Component classes
β β βββ Navigation.js
β β βββ Hero.js
β β βββ About.js
β β βββ Experience.js
β β βββ Projects.js
β β βββ Skills.js
β β
β βββ utils/ # Utility functions
β βββ dom.js # DOM manipulation helpers
β βββ animations.js # Animation utilities
β
βββ css/ # CSS Modules
β βββ base.css # Variables, reset, global styles
β βββ navigation.css
β βββ hero.css
β βββ about.css
β βββ experience.css
β βββ projects.css
β βββ skills.css
β βββ scroll-progress.css
β
βββ data/ # Data files
βββ portfolio.js # Centralized portfolio data
- Reusable Components: Each section is a separate component
- Template Engine: Simple templating system with
{{variable}}and{{#each}}syntax - Lifecycle Hooks: Components support
onMount()andonUnmount()hooks - State Management: Components can manage their own state
- Component-Based Styles: Each component has its own CSS file
- Easy Maintenance: Update styles without affecting other components
- Organized Structure: Clear separation of concerns
- Centralized Data: All portfolio data in
data/portfolio.js - Easy Updates: Update content in one place
- Type-Safe: Clear data structure
- DOM Helpers: Simplified DOM manipulation
- Animation Utilities: Reusable animation functions
- Router: Navigation handling (ready for future expansion)
Since this uses ES6 modules, you need to run it through a local server:
Option 1: Using Python
# Python 3
python3 -m http.server 8000
# Python 2
python -m SimpleHTTPServer 8000Option 2: Using Node.js (http-server)
npx http-server -p 8000Option 3: Using VS Code Live Server
- Install the "Live Server" extension
- Right-click on
index.htmland select "Open with Live Server"
Then open http://localhost:8000 in your browser.
- Create HTML Template (
components/YourComponent.html):
<div class="your-component">
<h2>{{title}}</h2>
<p>{{description}}</p>
</div>- Create Component Class (
js/components/YourComponent.js):
import { Component } from '../core/Component.js';
import { ComponentLoader, TemplateEngine } from '../core/Component.js';
export class YourComponent extends Component {
constructor(props) {
super(props);
}
async render() {
const template = await ComponentLoader.load('./components/YourComponent.html');
return TemplateEngine.render(template, this.props);
}
}- Create CSS (
css/your-component.css):
.your-component {
/* Your styles */
}- Import CSS in
style.css:
@import url('./css/your-component.css');- Use in App (
js/app.js):
import { YourComponent } from './components/YourComponent.js';
// In render method:
const yourComponent = new YourComponent({ title: 'Title', description: 'Desc' });
await yourComponent.mount('#app', true);<h1>{{name}}</h1>{{#each items}}
<div>{{title}}</div>
{{/each}}{{#each experiences}}
<div>
<h3>{{title}}</h3>
<ul>
{{#each responsibilities}}
<li>{{this}}</li>
{{/each}}
</ul>
</div>
{{/each}}{{#if showContent}}
<p>Content here</p>
{{/if}}class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
async render() {
// Return HTML string
}
onMount() {
// Called after component is mounted
}
setState(newState) {
// Update state and re-render
}
}// Replace content
await component.mount('#container');
// Append content
await component.mount('#container', true);- Use CSS variables from
base.cssfor colors and gradients - Keep component styles in their respective CSS files
- Follow BEM naming convention for complex components
- Use mobile-first responsive design
Update data/portfolio.js to modify content:
export const portfolioData = {
personal: { ... },
experience: [ ... ],
projects: [ ... ],
skills: { ... }
};- Add routing for multi-page support
- Implement state management system
- Add component caching
- Build system for production
- Add TypeScript support
- Implement lazy loading for components
This project is open source and available for personal use.