Article Summary
Personal websites often suffer from build-tool bloat. By bypassing frameworks and building this site using raw HTML, vanilla CSS, and simple vanilla JavaScript, we achieve nearly perfect performance metrics, total search engine indexability, and clean code that is easy to extend.
1. Philosophical Foundation: No Frameworks
In modern web development, standard practice calls for React, Next.js, or TailwindCSS, even for simple informational sites. For a personal digital portfolio, these frameworks introduce overhead: larger download footprints, Hydration latency, and fragile dependency trees that break after a few years of inactivity.
This website was intentionally built to be zero-dependency:
- No build steps: The raw HTML files served to visitors are the exact source files checked into version control.
- Vanilla styling: Pure CSS stylesheets structured around Custom Properties (CSS variables) organize spacing, typography, and dark/light modes.
- Vanilla script behavior: Responsive menus, scrolling progress, and live site searches are implemented in native modern JavaScript.
2. Designing with CSS Variables
To avoid Tailwind or Sass preprocessors, we structured main.css around CSS custom
properties inside a :root scope. This allows global changes to colors, font sizes, and
layout gaps from a single location:
:root {
/* Color Palette */
--bg-primary: #0b0f19;
--bg-surface: #111827;
--bg-surface-elevated: #1f2937;
--text-primary: #f3f4f6;
--text-secondary: #9ca3af;
--text-muted: #6b7280;
--color-primary: #6366f1;
--color-primary-hover: #4f46e5;
/* Font Family Tokens */
--font-body: 'Inter', system-ui, -apple-system, sans-serif;
--font-display: 'Outfit', var(--font-body);
/* Spacing Scale (8px Grid) */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-4: 1rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-12: 3rem;
}
Because CSS custom properties are calculated dynamically in the browser, changing themes or layout styles is as simple as toggling a class on the root element.
3. Client-Side Live Search Engine
Without an active server backend, how do we implement a live search box across projects, research
articles, and blog entries? We store search data inside a simple data/site.json (or read
the DOM structure directly) and index it client-side:
// Client-side search implementation
async function performSearch(query) {
const response = await fetch('/data/site.json');
const index = await response.json();
const searchResults = [];
const cleanQuery = query.toLowerCase().trim();
if (!cleanQuery) return [];
for (const item of index.documents) {
const titleMatch = item.title.toLowerCase().includes(cleanQuery);
const descMatch = item.description.toLowerCase().includes(cleanQuery);
const contentMatch = item.content ? item.content.toLowerCase().includes(cleanQuery) : false;
if (titleMatch || descMatch || contentMatch) {
let score = 0;
if (titleMatch) score += 10;
if (descMatch) score += 5;
if (contentMatch) score += 2;
searchResults.push({ ...item, score });
}
}
return searchResults.sort((a, b) => b.score - a.score);
}
This avoids hosting databases or paying for third-party SaaS indexing solutions while returning results in milliseconds.
4. SEO & Structured Metadata
To ensure maximum visibility on search engines, every page on the site implements strict metadata tags, canonical URLs, and Google-readable schema types:
- Breadcrumbs Navigation: Provides semantic microdata links (using schema.org microdata arrays) so search robots understand structural depth.
- JSON-LD Structured Data: Injects metadata (such as
BlogPosting,SoftwareApplication, orScholarlyArticle) directly into page headers. - Open Graph & Twitter Meta: Curates specific title, image, and description overrides to format previews cleanly when shared on social networks.
5. Performance & Verification
Bypassing complex client frameworks results in excellent speed metrics under Chrome Lighthouse audits:
| Lighthouse Category | Score achieved | Metric Detail |
|---|---|---|
| Performance | 100 / 100 | First Contentful Paint: 0.2s |
| Accessibility | 100 / 100 | Strict contrast, screen reader aria attributes |
| Best Practices | 100 / 100 | HTTPS, no unsafe script execution, modern libraries |
| SEO | 100 / 100 | Valid structured schemas, canonical links, descriptive tags |
6. Future Evolution
As the lab expands, we intend to implement a small static building step in Python or Rust to
automatically generate data/site.json indexes and compile HTML template files, maintaining
our zero-dependency stance for the browser client.