Cloud-native portfolio platform powering bjornmelin.io. Static export built with React 19, Next.js 16, and AWS CDK infrastructure. Deployed to S3 with CloudFront CDN. Requires Node.js 24.x LTS.
- Features
- Documentation
- Architecture
- Project Structure
- Getting Started
- Tech Stack
- AWS Services
- Development Scripts
- Docker
- Releasing
- Infrastructure Tests
- Author
- License
- AWS Infrastructure: S3, CloudFront, Route 53, ACM, Lambda via AWS CDK
- CI/CD: GitHub Actions with OIDC-based AWS role assumption
- Multi-Environment: Development, staging, and production configurations
- Static Export: Pre-rendered HTML with optimized assets
- Next.js 16 App Router: Server Components (build-time), static export (
output: 'export') - React 19: Modern React features with smaller client bundles
- TypeScript: Strict mode with Zod runtime validation
- Tailwind CSS: Utility-first styling with shadcn/ui components
- Image Optimization: Pre-generated WebP variants via Sharp (static export compatible)
- Bundle Analysis: Next.js built-in analyzer (
pnpm analyze) - Modern Targets: Browserslist configured for ES6 module support
graph TB
subgraph "Global Edge Network"
CF[CloudFront Distribution]
end
subgraph "Frontend"
S3[S3 Bucket]
CF --> S3
end
subgraph "API Layer"
LAMBDA[Contact Form Lambda]
RESEND[Resend API]
end
subgraph "DNS & SSL"
R53[Route 53]
ACM[ACM Certificate]
end
CF --> LAMBDA
LAMBDA --> RESEND
R53 --> CF
ACM --> CF
sequenceDiagram
participant User
participant Frontend
participant Lambda
participant Resend
User->>Frontend: Submit Contact Form
Frontend->>Lambda: POST ${NEXT_PUBLIC_API_URL}/contact
Lambda->>Resend: Send Email
Resend-->>Lambda: Email Sent
Lambda-->>Frontend: Success Response
Frontend-->>User: Show Success Message
graph LR
subgraph "DNS Management"
R53[Route 53]
ZONE[Hosted Zone]
end
subgraph "Content Delivery"
CF[CloudFront]
S3[S3 Origin]
ACM[SSL Certificate]
end
R53 --> CF
CF --> S3
ACM --> CF
bjornmelin-platform-io/
├── .github/ # GitHub Actions workflows
├── docs/ # Project documentation
│ ├── api/ # API documentation
│ ├── architecture/ # Architecture docs
│ ├── deployment/ # Deployment guides
│ └── development/ # Development guides
├── infrastructure/ # CDK infrastructure code
│ ├── bin/ # CDK app entry
│ └── lib/ # Infrastructure code
│ ├── functions/ # Lambda functions
│ ├── stacks/ # CDK stacks
│ └── types/ # Stack types
├── public/ # Static assets
│ ├── certifications/ # AWS certifications
│ ├── headshot/ # Profile images
│ └── projects/ # Project images
├── src/ # Application source
│ ├── app/ # Next.js 16 App Router
│ │ └── fonts/ # Custom fonts
│ ├── components/ # React components
│ ├── data/ # Static data
│ ├── hooks/ # Custom hooks
│ ├── lib/ # Utilities
│ └── types/ # TypeScript types
├── image-loader.ts # next/image custom loader (static export)
├── scripts/ # Build/deploy utilities (includes image generation)
└── next.config.mjs # Next.js configuration- Frontend: Next.js 16 static export with App Router
- Infrastructure: AWS CDK for resource provisioning
- CI/CD: GitHub Actions for automated deployments
- CDN: CloudFront with Route 53 DNS
- API: Lambda function with Resend for contact form (infrastructure-deployed)
Node.js >= 24.0.0 (LTS)
pnpm (via Corepack)
AWS CLI configuredEnable Corepack and activate the pinned pnpm version from package.json:
corepack enable
corepack use $(node -p "require('./package.json').packageManager")# Clone repository
git clone https://github.com/bjornmelin/bjornmelin-platform-io.git
cd bjornmelin-platform-io
# Install dependencies
pnpm install
# Configure AWS credentials
aws configure
# Configure local environment (local-only values)
cp .env.example .env.local
# Note: Production configuration is provided by the GitHub Environment (vars)
# and AWS SSM/Secrets. No .env.production is used.# Deploy infrastructure (from repo root)
pnpm -C infrastructure install
pnpm -C infrastructure cdk deploy# Start development server
pnpm devFrontend:
Core:
- React 19.2.3
- Next.js 16.1.2
- TypeScript 5.9.3
UI:
- Tailwind CSS
- shadcn/ui
- GeistVF Font
Build:
- Sharp-based WebP variants (static export)
- Next.js built-in analyzer (`pnpm analyze`)
- Browserslist (ES6 module targets)
Infrastructure:
AWS:
- CDK
- CloudFront
- S3
- Route 53
- ACM
- Lambda
Email:
- Resend
Development:
Tools:
- pnpm 10.28.0 (Corepack)
- Biome (lint + format)
- Vitest (unit tests)
- Playwright (E2E tests)- CloudFront: CDN distribution with custom domain
- Route 53: DNS management and domain routing
- ACM: SSL/TLS certificate management
- S3: Static asset hosting
- Lambda: Contact form handler
- Resend: Email delivery (via API)
- CDK: Infrastructure as code
- CloudWatch: Logging and monitoring
- IAM: Role-based access control
# Development
pnpm dev # Start development server
pnpm build # Build and optimize images
pnpm start # Serve static export
pnpm serve # Serve static export (alternative)
# Quality
pnpm lint # Run Biome lint/format checks
pnpm format:check # Run Biome format check
pnpm type-check # TypeScript type checking
# Testing
pnpm test # Run unit tests
pnpm test:coverage # Run unit tests with coverage
pnpm test:e2e # Run E2E tests
pnpm test:e2e:ui # Run Playwright in UI mode
pnpm test:e2e:report # Open Playwright HTML report
# Analysis
pnpm analyze # Build with bundle analyzer
# Infrastructure
pnpm -C infrastructure cdk deploy # Deploy AWS infrastructureBuild the production image (requires Docker Desktop/daemon running):
docker build -t platform-io:node24 .Run the container and serve the exported site on port 8080:
docker run --rm -p 8080:80 platform-io:node24Open http://localhost:8080 in your browser. Use Ctrl+C to stop the container.
Releases are automated using release-please.
Push commits with Conventional Commits format to main,
and release-please will open a Release PR. Merge it to create a tagged GitHub Release.
See docs/development/releasing.md for full details.
CDK assertions are available under infrastructure/test/ using Vitest.
See infrastructure/README.md#tests for commands.
AWS-certified Solutions Architect, Developer, SysOps Administrator, and Machine Learning Engineer. Connect on:
This project is licensed under the MIT License. See the LICENSE file for details.
If you use this project in your research or work:
@misc{melin2026portfolio,
author = {Melin, Bjorn},
title = {bjornmelin-platform-io: Portfolio Platform},
year = {2026},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/bjornmelin/bjornmelin-platform-io}},
commit = {main}
}- AWS Documentation
- AWS CDK Patterns Community
- Next.js Documentation
Built with React 19 + Next.js 16 by Bjorn Melin.





