Hardening a Developer Portfolio
A multi-part series on building production-ready developer platforms
A multi-part series on building production-ready developer platforms

"Cybersecurity protection illustration featuring 3D shield with padlock icon, security rings, and verification checkmarks representing data security and compliance"
Photo by Perplexity Labs
3 posts in this series
Feel free to send us a message with your thoughts, or learn more about us!
Implement event-driven architecture with Inngest for instant API responses, automatic retries, and production-grade background processing. Real code from a live portfolio.
How I used Next.js App Router, Tailwind v4, and shadcn/ui to build a production-ready developer portfolio with modern architecture patterns.
On January 13, 2026, Node.js released security patches for 8 vulnerabilities (3 HIGH, 4 MEDIUM, 1 LOW) affecting all active release lines. This post breaks down each CVE, explains who is affected, and provides actionable remediation guidance.
Part 2 of 3
Series Background: This is a follow-up to Shipping a Developer Portfolio. where I built the foundation for what would become a comprehensive developer platform. This series documents the security hardening, performance optimization, and production features that transformed a simple portfolio into an enterprise-ready system
After building the initial portfolio, I systematically addressed security vulnerabilities, performance bottlenecks, and scalability concerns to create a production-ready platform. What started as a simple site now includes comprehensive monitoring, automated security headers, background job processing, and enterprise-grade features.
This series documents the patterns and decisions that took it from prototype to production.
Current Architecture (December 2025):
Production-ready portfolios require systematic security hardening, performance optimization, and scalability planning. This post demonstrates how to build enterprise-grade developer platforms with CSP, rate limiting, Core Web Vitals monitoring, and background job processing.
Content Security Policy (CSP) Implementation
The site had zero , making it vulnerable to and clickjacking. I implemented a defense-in-depth approach using Next.js middleware and Vercel configuration.
What I Built:
src/middleware.ts) for HTML routesvercel.json fallbackKey Learnings:
Technical Highlights:
// Generate unique nonce per request
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
// Build strict CSP
const csp = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' https://va.vercel-scripts.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
`
.replace(/
Implement CSP via Next.js middleware for reliable header enforcement. Use defense-in-depth with both middleware and Vercel config. Zero external dependencies for rate limiting works perfectly for serverless deployments.
Rate Limiting Implementation
The contact form API endpoint had no rate limiting, making it vulnerable to spam and abuse. I implemented a zero-dependency, in-memory rate limiter.
What I Built:
src/lib/rate-limit.ts (146 lines)X-Forwarded-For)X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset)scripts/test-rate-limit.mjs)Key Learnings:
Technical Highlights:
// Rate limiter with automatic cleanup
export class RateLimiter {
private requests = new Map<string, RequestRecord>();
async check(identifier: string): Promise<RateLimitResult> {
const now = Date.now();
const record = this.requests.get
Implement defense-in-depth CSP with Next.js middleware + Vercel config, zero-dependency rate limiting for API endpoints, and automated security header validation. Monitor for XSS, clickjacking, and DDoS patterns using standard HTTP security headers.
(Interaction to Next Paint) Improvements
Google’s Core Web Vitals showed poor INP scores (664ms+) on navigation links. The culprit: Next.js hover prefetching blocking the main thread.
What I Fixed:
<Link> components (prefetch={false})will-change-auto, contain: layout style)transform: translateZ(0))useTransitionKey Learnings:
useTransition keeps UI responsive during state updatesTechnical Highlights:
// Non-blocking theme toggle
export function ThemeToggle() {
const [isPending, startTransition] = useTransition();
const { setTheme, theme } = useTheme();
const toggleTheme = () => {
startTransition(() => {
setTheme(theme === 'light' ? 'dark'
GitHub Contributions Heatmap
I added a live GitHub contributions heatmap to the homepage to showcase activity.
What I Built:
/api/github-contributions)react-calendar-heatmapGITHUB_TOKEN env var for higher rate limitsKey Learnings:
Technical Highlights:
// Fetch with caching
const fetchContributions = async (): Promise<ContributionResponse> => {
// Check cache first
const cached = localStorage.getItem(CACHE_KEY);
if (cached) {
const data = JSON.parse(cached);
if (Date.now() - data.timestamp < CACHE_DURATION
AI Contributor Guide
I created comprehensive instructions for AI coding assistants (GitHub Copilot, Cursor, etc.) to maintain code quality and architectural consistency.
What I Built:
.github/copilot-instructions.mdKey Learnings:
Results:
Future improvements on my radar:
Taking a project from “works on my machine” to “production-ready” requires intentional hardening. Security, performance, and developer experience all need attention.
The good news? Modern frameworks like Next.js make it easier than ever. Middleware for CSP, server actions for rate limiting, and React’s concurrent features for performance, the tools are there.
The platform is now deployed in production with comprehensive monitoring, automated security scanning, and enterprise-grade features. The architecture patterns documented here have proven themselves in real-world usage with excellent Core Web Vitals scores and zero security incidents.
Now it’s your turn. What production features does your developer platform need?
Results:
frame-ancestors 'none'Results:
npm run test:rate-limitResults:
Results: