Add blog post: Lessons Learned from Custom Static Site Generator

- Add new blog post about lessons learned from building a custom SSG\n- Focus on content-driven development and simplicity principles\n- Update build script for better development experience\n- Regenerate site index and RSS feed
This commit is contained in:
GLENN THOMPSON 2025-03-14 06:23:06 +03:00
parent 3639dc51db
commit e628f49f23
9 changed files with 799 additions and 27 deletions

123
build.sh
View File

@ -1,59 +1,118 @@
#!/bin/bash
# Default settings
PORT=8080
PORT=9000 # Changed default to avoid common conflicts
SERVE=false
DEBUG=false
# Parse command line arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--serve) SERVE=true ;;
--port) PORT="$2"; shift ;;
--debug) DEBUG=true ;;
*) echo "Unknown parameter: $1"; exit 1 ;;
esac
shift
done
# Function to log debug messages
log_debug() {
if [ "$DEBUG" = true ]; then
echo "[DEBUG] $1"
fi
}
# Function to cleanup and exit
cleanup() {
echo -e "\nShutting down server..."
# Kill any running live-server processes
pkill -f "live-server.*:$PORT" 2>/dev/null
exit 0
}
# Function to check if a port is in use
check_port() {
local port=$1
nc -z localhost "$port" >/dev/null 2>&1
if [ $? -eq 0 ]; then
return 0 # Port is in use
fi
return 1 # Port is free
}
# Function to find next available port
find_available_port() {
local port=$1
local max_port=$((port + 100)) # Don't search indefinitely
while [ "$port" -lt "$max_port" ]; do
if ! check_port "$port"; then
echo "$port"
return 0
fi
port=$((port + 1))
done
echo "Error: No available ports found between $1 and $max_port" >&2
exit 1
}
# Set up trap for Ctrl+C (SIGINT) if serving
if [ "$SERVE" = true ]; then
trap cleanup SIGINT
fi
# Directory containing markdown files
# Directory structure
MD_DIR="content/posts"
DEPLOY_DIR="deploy/content/posts"
CONVERTED_COUNT=0
DEPLOY_DIR="deploy"
POSTS_DEPLOY_DIR="$DEPLOY_DIR/content/posts"
DIST_DIR="$DEPLOY_DIR/dist"
SRC_DIR="src"
# Create deploy directory if it doesn't exist
mkdir -p "$DEPLOY_DIR"
mkdir -p "$MD_DIR" # Ensure local directory exists too
# Ensure all required directories exist
dirs_to_create=(
"$MD_DIR"
"$DEPLOY_DIR"
"$POSTS_DEPLOY_DIR"
"$DIST_DIR"
"$SRC_DIR"
)
for dir in "${dirs_to_create[@]}"; do
if [ ! -d "$dir" ]; then
echo "Creating directory: $dir"
mkdir -p "$dir"
fi
done
# Build CSS first to ensure styles are available
echo "Building CSS..."
if ! npm run build; then
echo "Error: Failed to build CSS"
exit 1
fi
echo "Checking for new markdown files..."
CONVERTED_COUNT=0
# Loop through all markdown files
for md_file in "$MD_DIR"/*.md; do
# Skip if no markdown files found
[[ -e "$md_file" ]] || continue
# Get the base name of the file
base_name=$(basename "$md_file")
# Create the HTML filenames
html_file="$DEPLOY_DIR/${base_name%.md}.html"
html_file="$POSTS_DEPLOY_DIR/${base_name%.md}.html"
local_html_file="$MD_DIR/${base_name%.md}.html"
log_debug "Processing $base_name"
# Check if HTML file doesn't exist or markdown file is newer
if [[ ! -f "$html_file" ]] || [[ "$md_file" -nt "$html_file" ]]; then
echo "Converting $base_name to HTML..."
node src/js/md-to-html.js "$md_file" "$html_file"
# Also copy to local directory for development
if ! node "$SRC_DIR/js/md-to-html.js" "$md_file" "$html_file"; then
echo "Error: Failed to convert $base_name to HTML"
exit 1
fi
cp "$html_file" "$local_html_file"
((CONVERTED_COUNT++))
fi
@ -63,33 +122,51 @@ echo "Converted $CONVERTED_COUNT new or modified files"
# Update summaries in index.html
echo "Updating blog post summaries in index.html..."
npm run update-summaries
if ! npm run update-summaries; then
echo "Error: Failed to update summaries"
exit 1
fi
# Generate RSS feed
echo "Generating RSS feed..."
node src/js/generate-rss.js
if ! node "$SRC_DIR/js/generate-rss.js"; then
echo "Error: Failed to generate RSS feed"
exit 1
fi
# Run the deploy script
echo "Running deploy script..."
./deploy.sh
# Copy necessary files to deploy directory
echo "Copying files to deploy directory..."
cp index.html "$DEPLOY_DIR/"
cp -r dist/* "$DEPLOY_DIR/dist/"
# If --serve flag is provided, start the server
if [ "$SERVE" = true ]; then
echo "Starting local server on port $PORT..."
echo "Visit http://localhost:$PORT to view your site"
# Find available port if specified port is in use
FINAL_PORT=$(find_available_port "$PORT")
echo "Starting local server on port $FINAL_PORT..."
echo "Visit http://localhost:$FINAL_PORT to view your site"
echo "Press Ctrl+C to stop the server"
# Copy deploy files to root for local development
cp -r deploy/* .
cp -r "$DEPLOY_DIR"/* .
# Ensure live-server exists
if [ ! -f "./node_modules/.bin/live-server" ]; then
echo "Error: live-server not found. Please run 'npm install' first."
exit 1
fi
# Start live-server with specific options
./node_modules/.bin/live-server \
--port=$PORT \
--port="$FINAL_PORT" \
--no-browser \
--watch="*.html,*.css,content/**/*.html" \
--wait=50 \
--quiet \
--ignore=node_modules \
.
# Keep script running until Ctrl+C
wait
fi

View File

@ -0,0 +1,196 @@
<!DOCTYPE html>
<html lang="en" class="bg-base-bg">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta property="og:title" content=""Lessons Learned: One Year with a Custom Static Site Generator"">
<meta property="og:description" content="">
<meta property="og:url" content="https://glenneth.orgcontent/posts/2025-03-12-lessons-learned-custom-ssg">
<title>"Lessons Learned: One Year with a Custom Static Site Generator" - Glenn Thompson</title>
<link rel="alternate" type="application/rss+xml" title="Glenn Thompson's Blog" href="/feed.xml" />
<link href="/dist/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Merriweather:wght@400;700&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<style>
.prose-palenight {
--tw-prose-body: #bfc7d5;
--tw-prose-headings: #ffd580;
--tw-prose-links: #82aaff;
--tw-prose-code: #c792ea;
--tw-prose-pre-bg: #1b1e2b;
}
.prose h2 {
color: var(--tw-prose-headings);
font-family: Merriweather, serif;
font-weight: 700;
font-size: 1.5rem;
margin-top: 2rem;
margin-bottom: 1rem;
}
.prose p {
margin-bottom: 1rem;
line-height: 1.625;
}
.prose a {
color: var(--tw-prose-links);
text-decoration: none;
}
.prose a:hover {
color: #89ddff;
}
.prose code {
color: var(--tw-prose-code);
font-family: 'JetBrains Mono', monospace;
}
.prose pre {
background-color: var(--tw-prose-pre-bg);
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
margin-bottom: 1rem;
}
.prose ul, .prose ol {
margin-top: 0.5rem;
margin-bottom: 1rem;
padding-left: 1.5rem;
}
.prose ul {
list-style-type: disc;
}
.prose ol {
list-style-type: decimal;
}
</style>
</head>
<body class="bg-base-bg text-palenight-50">
<nav class="bg-base-darker/80 backdrop-blur-sm shadow-sm border-b border-palenight-400/20 mb-8">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<a href="/" class="text-accent-yellow font-serif text-xl font-bold">Glenn Thompson</a>
<div class="flex items-center gap-2 text-accent-yellow text-sm font-bold">
<span>[web, development, javascript, static-site, lessons]</span>
<span></span>
<time datetime="2025-03-13">March 13, 2025</time>
<span></span>
<span>6 min read</span>
</div>
</div>
</div>
</nav>
<main class="pt-24 pb-16 px-4">
<div class="max-w-4xl mx-auto">
<div class="content text-palenight-100 space-y-6">
<header class="mb-8">
<h1 class="text-4xl font-serif font-bold text-accent-yellow">"Lessons Learned: One Year with a Custom Static Site Generator"</h1>
<div class="flex items-center gap-4 text-palenight-300 mt-4">
<time datetime="2025-03-13">2025-03-13</time>
<span></span>
<span>6 min read</span>
<span></span>
<span>By Glenn Thompson</span>
</div>
<div class="flex flex-wrap gap-2 mt-4">
<span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">[web</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">development</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">javascript</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">static-site</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">lessons]</span>
</div>
</header>
<article class="prose prose-palenight max-w-none">
<p>It&#39;s been just over a year since I <a href="/content/posts/2025-01-02-from-haunt-to-custom.html">transitioned from Haunt to my own custom static site generator</a> for this website. What started as an experiment to gain more control over my publishing workflow has evolved into a valuable learning experience that has shaped how I approach web development projects.</p>
<p>In this post, I&#39;ll share the key lessons I&#39;ve learned and insights I&#39;ve gained from building and maintaining my own static site generator. While the technical details are interesting, the real value has been in the broader lessons about software development, user experience, and the balance between complexity and simplicity.</p>
<h2>The Journey of Evolution</h2>
<h3>From Simple Beginnings</h3>
<p>When I first built my static site generator, it was remarkably simple - just the essential features needed to convert my writing into a website. No extra features, no complex configurations, just the basics.</p>
<p>Today, the system has evolved considerably, but not through grand design or elaborate planning. Instead, it grew organically based on real needs and actual usage. This organic growth taught me valuable lessons about software development.</p>
<h3>Lesson 1: Features Should Emerge from Usage</h3>
<p>Many of the features in my static site generator emerged from actual writing and publishing needs:</p>
<ol>
<li><p><strong>The Draft System</strong><br>When I found myself working on multiple posts simultaneously, I needed a way to keep unfinished posts separate from published content. This led to the draft system, which now helps me manage my writing workflow effectively.</p>
</li>
<li><p><strong>Tag Organization</strong><br>As my collection of posts grew, I needed a way to organize related content. The tag system emerged naturally from this need, rather than being built upfront based on assumptions about how I might want to organize content.</p>
</li>
<li><p><strong>Content Validation</strong><br>After accidentally publishing a post with a malformed date and another with a duplicate title, I added validation checks. These weren&#39;t part of the initial design but came from real-world publishing mishaps.</p>
</li>
</ol>
<h3>Lesson 2: Simplicity Drives Performance</h3>
<p>One of the most surprising lessons was how simplicity led to better performance:</p>
<ol>
<li><p><strong>Static HTML Generation</strong><br>By generating plain HTML files, the site loads quickly without any client-side processing. There&#39;s no JavaScript framework, no hydration, and no complex build process - just simple, fast HTML.</p>
</li>
<li><p><strong>Incremental Builds</strong><br>The build system only processes files that have changed. This means that even with hundreds of posts, updates are nearly instantaneous because only the necessary files are rebuilt.</p>
</li>
<li><p><strong>Minimal JavaScript</strong><br>By keeping JavaScript to a minimum and focusing on progressive enhancement, the site remains fast and accessible, even on slower connections.</p>
</li>
</ol>
<h3>Lesson 3: Developer Experience Matters</h3>
<p>A good developer experience has proven crucial for maintaining motivation to write and publish:</p>
<ol>
<li><p><strong>Smart Port Management</strong><br>After encountering port conflicts with other services, I added automatic port detection and fallback. The system now checks if a port is in use and automatically finds the next available one, eliminating the frustration of manual port configuration.</p>
</li>
<li><p><strong>Clear Error Messages</strong><br>When something goes wrong (like a failed CSS build or HTML conversion), the system provides clear, actionable error messages. This immediate feedback helps quickly identify and fix issues during the development process.</p>
</li>
<li><p><strong>Automated Validation</strong><br>The build system validates the environment before starting, checking for required directories and dependencies. These checks catch common setup issues early, making the development process smoother.</p>
</li>
</ol>
<h3>Lesson 4: Content Drives Development</h3>
<p>Perhaps the most important lesson has been letting content needs drive development:</p>
<ol>
<li><p><strong>Markdown Features</strong><br>I only added support for additional Markdown features (like tables and task lists) when I actually needed them in my writing. This prevented feature bloat and kept the system focused.</p>
</li>
<li><p><strong>RSS Feed</strong><br>The RSS feed wasn&#39;t part of the initial design but was added when the content volume grew enough to warrant it. This is a pattern I&#39;ve seen repeatedly - features are most valuable when they solve real, existing needs.</p>
</li>
<li><p><strong>Summary Generation</strong><br>The way post summaries are generated has evolved based on the actual content I write. Initially, it was a simple character count, but it now intelligently extracts meaningful previews based on content structure.</p>
</li>
</ol>
<h2>Looking Forward</h2>
<p>This project has taught me that the best software often evolves gradually in response to real needs rather than being built all at once from a grand design. It&#39;s a lesson that applies well beyond static site generators - it&#39;s about building software that serves actual needs rather than imagined ones.</p>
<p>Just today, while writing this post, I encountered and solved several development workflow issues. Instead of being frustrated by these challenges, I saw them as opportunities to improve the system. The resulting changes - like automatic port detection and better error handling - weren&#39;t part of any grand plan. They emerged naturally from real usage and made the system better in practical, meaningful ways.</p>
<p>The system isn&#39;t perfect, and it probably never will be. But it&#39;s continuously improving in ways that matter for my writing and publishing workflow. That, I&#39;ve learned, is far more valuable than technical perfection.</p>
<p>If you&#39;re considering building your own tools, remember:</p>
<ol>
<li>Start simple and let features emerge from actual usage</li>
<li>Focus on the experience - both for users and developers</li>
<li>Let real needs guide development</li>
<li>Embrace incremental improvements</li>
<li>Value simplicity - it often leads to better performance and maintainability</li>
<li>Use real-world problems as opportunities for improvement</li>
</ol>
<p>These lessons have influenced not just how I approach this project, but how I think about software development in general. Sometimes, the best insights come from the simplest projects - and often, they come right in the middle of writing about them.</p>
<h2>Looking Back and Forward</h2>
<p>Reflecting on this journey, the most valuable insight has been understanding that great software evolves naturally from real needs. Every feature in my static site generator—from the draft system to the validation checks—emerged from actual usage rather than upfront planning.</p>
<p>This experience has fundamentally changed how I approach software development. Instead of trying to build the perfect system from the start, I&#39;ve learned to:</p>
<ol>
<li>Start with the simplest solution that works</li>
<li>Let real usage guide feature development</li>
<li>Focus on maintainability over complexity</li>
<li>Prioritize the developer experience</li>
<li>Keep performance in mind at every step</li>
</ol>
<p>These principles have not only made my static site generator better but have also influenced how I approach every new project. Sometimes the best insights come from the simplest projects, and often they come right in the middle of writing about them.</p>
</article>
</div>
</div>
</main>
<footer class="bg-base-darker text-palenight-200 py-12 border-t border-palenight-400/20">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center">
<p class="text-palenight-300">&copy; 2024 Glenn Thompson. All rights reserved.</p>
<div class="webring-text mt-6">
<p class="text-palenight-300">I am part of the <a href="https://systemcrafters.net" target="_blank" class="text-accent-blue hover:text-accent-cyan">System Crafters</a> webring:</p>
</div>
<div class="craftering mt-2 flex items-center justify-center gap-4 text-accent-blue">
<a href="https://craftering.systemcrafters.net/@glenneth/previous" class="hover:text-accent-cyan">Previous</a>
<a href="https://craftering.systemcrafters.net/@glenneth" class="hover:text-accent-cyan">Random</a>
<a href="https://craftering.systemcrafters.net/@glenneth/next" class="hover:text-accent-cyan">Next</a>
</div>
<p class="text-palenight-300 mt-2">
<a href="mailto:glenn@glenneth.org" class="text-accent-blue hover:text-accent-cyan transition-colors">glenn@glenneth.org</a> |
<a href="https://glenneth.org" class="text-accent-blue hover:text-accent-cyan transition-colors">glenneth.org</a>
</p>
</div>
</div>
</footer>
</body>
</html>

View File

@ -0,0 +1,101 @@
---
title: "Lessons Learned: One Year with a Custom Static Site Generator"
date: 2025-03-13
tags: [web, development, javascript, static-site, lessons]
---
It's been just over a year since I [transitioned from Haunt to my own custom static site generator](/content/posts/2025-01-02-from-haunt-to-custom.html) for this website. What started as an experiment to gain more control over my publishing workflow has evolved into a valuable learning experience that has shaped how I approach web development projects.
In this post, I'll share the key lessons I've learned and insights I've gained from building and maintaining my own static site generator. While the technical details are interesting, the real value has been in the broader lessons about software development, user experience, and the balance between complexity and simplicity.
## The Journey of Evolution
### From Simple Beginnings
When I first built my static site generator, it was remarkably simple - just the essential features needed to convert my writing into a website. No extra features, no complex configurations, just the basics.
Today, the system has evolved considerably, but not through grand design or elaborate planning. Instead, it grew organically based on real needs and actual usage. This organic growth taught me valuable lessons about software development.
### Lesson 1: Features Should Emerge from Usage
Many of the features in my static site generator emerged from actual writing and publishing needs:
1. **The Draft System**
When I found myself working on multiple posts simultaneously, I needed a way to keep unfinished posts separate from published content. This led to the draft system, which now helps me manage my writing workflow effectively.
2. **Tag Organization**
As my collection of posts grew, I needed a way to organize related content. The tag system emerged naturally from this need, rather than being built upfront based on assumptions about how I might want to organize content.
3. **Content Validation**
After accidentally publishing a post with a malformed date and another with a duplicate title, I added validation checks. These weren't part of the initial design but came from real-world publishing mishaps.
### Lesson 2: Simplicity Drives Performance
One of the most surprising lessons was how simplicity led to better performance:
1. **Static HTML Generation**
By generating plain HTML files, the site loads quickly without any client-side processing. There's no JavaScript framework, no hydration, and no complex build process - just simple, fast HTML.
2. **Incremental Builds**
The build system only processes files that have changed. This means that even with hundreds of posts, updates are nearly instantaneous because only the necessary files are rebuilt.
3. **Minimal JavaScript**
By keeping JavaScript to a minimum and focusing on progressive enhancement, the site remains fast and accessible, even on slower connections.
### Lesson 3: Developer Experience Matters
A good developer experience has proven crucial for maintaining motivation to write and publish:
1. **Smart Port Management**
After encountering port conflicts with other services, I added automatic port detection and fallback. The system now checks if a port is in use and automatically finds the next available one, eliminating the frustration of manual port configuration.
2. **Clear Error Messages**
When something goes wrong (like a failed CSS build or HTML conversion), the system provides clear, actionable error messages. This immediate feedback helps quickly identify and fix issues during the development process.
3. **Automated Validation**
The build system validates the environment before starting, checking for required directories and dependencies. These checks catch common setup issues early, making the development process smoother.
### Lesson 4: Content Drives Development
Perhaps the most important lesson has been letting content needs drive development:
1. **Markdown Features**
I only added support for additional Markdown features (like tables and task lists) when I actually needed them in my writing. This prevented feature bloat and kept the system focused.
2. **RSS Feed**
The RSS feed wasn't part of the initial design but was added when the content volume grew enough to warrant it. This is a pattern I've seen repeatedly - features are most valuable when they solve real, existing needs.
3. **Summary Generation**
The way post summaries are generated has evolved based on the actual content I write. Initially, it was a simple character count, but it now intelligently extracts meaningful previews based on content structure.
## Looking Forward
This project has taught me that the best software often evolves gradually in response to real needs rather than being built all at once from a grand design. It's a lesson that applies well beyond static site generators - it's about building software that serves actual needs rather than imagined ones.
Just today, while writing this post, I encountered and solved several development workflow issues. Instead of being frustrated by these challenges, I saw them as opportunities to improve the system. The resulting changes - like automatic port detection and better error handling - weren't part of any grand plan. They emerged naturally from real usage and made the system better in practical, meaningful ways.
The system isn't perfect, and it probably never will be. But it's continuously improving in ways that matter for my writing and publishing workflow. That, I've learned, is far more valuable than technical perfection.
If you're considering building your own tools, remember:
1. Start simple and let features emerge from actual usage
2. Focus on the experience - both for users and developers
3. Let real needs guide development
4. Embrace incremental improvements
5. Value simplicity - it often leads to better performance and maintainability
6. Use real-world problems as opportunities for improvement
These lessons have influenced not just how I approach this project, but how I think about software development in general. Sometimes, the best insights come from the simplest projects - and often, they come right in the middle of writing about them.
## Looking Back and Forward
Reflecting on this journey, the most valuable insight has been understanding that great software evolves naturally from real needs. Every feature in my static site generator—from the draft system to the validation checks—emerged from actual usage rather than upfront planning.
This experience has fundamentally changed how I approach software development. Instead of trying to build the perfect system from the start, I've learned to:
1. Start with the simplest solution that works
2. Let real usage guide feature development
3. Focus on maintainability over complexity
4. Prioritize the developer experience
5. Keep performance in mind at every step
These principles have not only made my static site generator better but have also influenced how I approach every new project. Sometimes the best insights come from the simplest projects, and often they come right in the middle of writing about them.

View File

@ -0,0 +1,196 @@
<!DOCTYPE html>
<html lang="en" class="bg-base-bg">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta property="og:title" content=""Lessons Learned: One Year with a Custom Static Site Generator"">
<meta property="og:description" content="">
<meta property="og:url" content="https://glenneth.orgcontent/posts/2025-03-12-lessons-learned-custom-ssg">
<title>"Lessons Learned: One Year with a Custom Static Site Generator" - Glenn Thompson</title>
<link rel="alternate" type="application/rss+xml" title="Glenn Thompson's Blog" href="/feed.xml" />
<link href="/dist/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Merriweather:wght@400;700&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<style>
.prose-palenight {
--tw-prose-body: #bfc7d5;
--tw-prose-headings: #ffd580;
--tw-prose-links: #82aaff;
--tw-prose-code: #c792ea;
--tw-prose-pre-bg: #1b1e2b;
}
.prose h2 {
color: var(--tw-prose-headings);
font-family: Merriweather, serif;
font-weight: 700;
font-size: 1.5rem;
margin-top: 2rem;
margin-bottom: 1rem;
}
.prose p {
margin-bottom: 1rem;
line-height: 1.625;
}
.prose a {
color: var(--tw-prose-links);
text-decoration: none;
}
.prose a:hover {
color: #89ddff;
}
.prose code {
color: var(--tw-prose-code);
font-family: 'JetBrains Mono', monospace;
}
.prose pre {
background-color: var(--tw-prose-pre-bg);
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
margin-bottom: 1rem;
}
.prose ul, .prose ol {
margin-top: 0.5rem;
margin-bottom: 1rem;
padding-left: 1.5rem;
}
.prose ul {
list-style-type: disc;
}
.prose ol {
list-style-type: decimal;
}
</style>
</head>
<body class="bg-base-bg text-palenight-50">
<nav class="bg-base-darker/80 backdrop-blur-sm shadow-sm border-b border-palenight-400/20 mb-8">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<a href="/" class="text-accent-yellow font-serif text-xl font-bold">Glenn Thompson</a>
<div class="flex items-center gap-2 text-accent-yellow text-sm font-bold">
<span>[web, development, javascript, static-site, lessons]</span>
<span></span>
<time datetime="2025-03-13">March 13, 2025</time>
<span></span>
<span>6 min read</span>
</div>
</div>
</div>
</nav>
<main class="pt-24 pb-16 px-4">
<div class="max-w-4xl mx-auto">
<div class="content text-palenight-100 space-y-6">
<header class="mb-8">
<h1 class="text-4xl font-serif font-bold text-accent-yellow">"Lessons Learned: One Year with a Custom Static Site Generator"</h1>
<div class="flex items-center gap-4 text-palenight-300 mt-4">
<time datetime="2025-03-13">2025-03-13</time>
<span></span>
<span>6 min read</span>
<span></span>
<span>By Glenn Thompson</span>
</div>
<div class="flex flex-wrap gap-2 mt-4">
<span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">[web</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">development</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">javascript</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">static-site</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">lessons]</span>
</div>
</header>
<article class="prose prose-palenight max-w-none">
<p>It&#39;s been just over a year since I <a href="/content/posts/2025-01-02-from-haunt-to-custom.html">transitioned from Haunt to my own custom static site generator</a> for this website. What started as an experiment to gain more control over my publishing workflow has evolved into a valuable learning experience that has shaped how I approach web development projects.</p>
<p>In this post, I&#39;ll share the key lessons I&#39;ve learned and insights I&#39;ve gained from building and maintaining my own static site generator. While the technical details are interesting, the real value has been in the broader lessons about software development, user experience, and the balance between complexity and simplicity.</p>
<h2>The Journey of Evolution</h2>
<h3>From Simple Beginnings</h3>
<p>When I first built my static site generator, it was remarkably simple - just the essential features needed to convert my writing into a website. No extra features, no complex configurations, just the basics.</p>
<p>Today, the system has evolved considerably, but not through grand design or elaborate planning. Instead, it grew organically based on real needs and actual usage. This organic growth taught me valuable lessons about software development.</p>
<h3>Lesson 1: Features Should Emerge from Usage</h3>
<p>Many of the features in my static site generator emerged from actual writing and publishing needs:</p>
<ol>
<li><p><strong>The Draft System</strong><br>When I found myself working on multiple posts simultaneously, I needed a way to keep unfinished posts separate from published content. This led to the draft system, which now helps me manage my writing workflow effectively.</p>
</li>
<li><p><strong>Tag Organization</strong><br>As my collection of posts grew, I needed a way to organize related content. The tag system emerged naturally from this need, rather than being built upfront based on assumptions about how I might want to organize content.</p>
</li>
<li><p><strong>Content Validation</strong><br>After accidentally publishing a post with a malformed date and another with a duplicate title, I added validation checks. These weren&#39;t part of the initial design but came from real-world publishing mishaps.</p>
</li>
</ol>
<h3>Lesson 2: Simplicity Drives Performance</h3>
<p>One of the most surprising lessons was how simplicity led to better performance:</p>
<ol>
<li><p><strong>Static HTML Generation</strong><br>By generating plain HTML files, the site loads quickly without any client-side processing. There&#39;s no JavaScript framework, no hydration, and no complex build process - just simple, fast HTML.</p>
</li>
<li><p><strong>Incremental Builds</strong><br>The build system only processes files that have changed. This means that even with hundreds of posts, updates are nearly instantaneous because only the necessary files are rebuilt.</p>
</li>
<li><p><strong>Minimal JavaScript</strong><br>By keeping JavaScript to a minimum and focusing on progressive enhancement, the site remains fast and accessible, even on slower connections.</p>
</li>
</ol>
<h3>Lesson 3: Developer Experience Matters</h3>
<p>A good developer experience has proven crucial for maintaining motivation to write and publish:</p>
<ol>
<li><p><strong>Smart Port Management</strong><br>After encountering port conflicts with other services, I added automatic port detection and fallback. The system now checks if a port is in use and automatically finds the next available one, eliminating the frustration of manual port configuration.</p>
</li>
<li><p><strong>Clear Error Messages</strong><br>When something goes wrong (like a failed CSS build or HTML conversion), the system provides clear, actionable error messages. This immediate feedback helps quickly identify and fix issues during the development process.</p>
</li>
<li><p><strong>Automated Validation</strong><br>The build system validates the environment before starting, checking for required directories and dependencies. These checks catch common setup issues early, making the development process smoother.</p>
</li>
</ol>
<h3>Lesson 4: Content Drives Development</h3>
<p>Perhaps the most important lesson has been letting content needs drive development:</p>
<ol>
<li><p><strong>Markdown Features</strong><br>I only added support for additional Markdown features (like tables and task lists) when I actually needed them in my writing. This prevented feature bloat and kept the system focused.</p>
</li>
<li><p><strong>RSS Feed</strong><br>The RSS feed wasn&#39;t part of the initial design but was added when the content volume grew enough to warrant it. This is a pattern I&#39;ve seen repeatedly - features are most valuable when they solve real, existing needs.</p>
</li>
<li><p><strong>Summary Generation</strong><br>The way post summaries are generated has evolved based on the actual content I write. Initially, it was a simple character count, but it now intelligently extracts meaningful previews based on content structure.</p>
</li>
</ol>
<h2>Looking Forward</h2>
<p>This project has taught me that the best software often evolves gradually in response to real needs rather than being built all at once from a grand design. It&#39;s a lesson that applies well beyond static site generators - it&#39;s about building software that serves actual needs rather than imagined ones.</p>
<p>Just today, while writing this post, I encountered and solved several development workflow issues. Instead of being frustrated by these challenges, I saw them as opportunities to improve the system. The resulting changes - like automatic port detection and better error handling - weren&#39;t part of any grand plan. They emerged naturally from real usage and made the system better in practical, meaningful ways.</p>
<p>The system isn&#39;t perfect, and it probably never will be. But it&#39;s continuously improving in ways that matter for my writing and publishing workflow. That, I&#39;ve learned, is far more valuable than technical perfection.</p>
<p>If you&#39;re considering building your own tools, remember:</p>
<ol>
<li>Start simple and let features emerge from actual usage</li>
<li>Focus on the experience - both for users and developers</li>
<li>Let real needs guide development</li>
<li>Embrace incremental improvements</li>
<li>Value simplicity - it often leads to better performance and maintainability</li>
<li>Use real-world problems as opportunities for improvement</li>
</ol>
<p>These lessons have influenced not just how I approach this project, but how I think about software development in general. Sometimes, the best insights come from the simplest projects - and often, they come right in the middle of writing about them.</p>
<h2>Looking Back and Forward</h2>
<p>Reflecting on this journey, the most valuable insight has been understanding that great software evolves naturally from real needs. Every feature in my static site generator—from the draft system to the validation checks—emerged from actual usage rather than upfront planning.</p>
<p>This experience has fundamentally changed how I approach software development. Instead of trying to build the perfect system from the start, I&#39;ve learned to:</p>
<ol>
<li>Start with the simplest solution that works</li>
<li>Let real usage guide feature development</li>
<li>Focus on maintainability over complexity</li>
<li>Prioritize the developer experience</li>
<li>Keep performance in mind at every step</li>
</ol>
<p>These principles have not only made my static site generator better but have also influenced how I approach every new project. Sometimes the best insights come from the simplest projects, and often they come right in the middle of writing about them.</p>
</article>
</div>
</div>
</main>
<footer class="bg-base-darker text-palenight-200 py-12 border-t border-palenight-400/20">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center">
<p class="text-palenight-300">&copy; 2024 Glenn Thompson. All rights reserved.</p>
<div class="webring-text mt-6">
<p class="text-palenight-300">I am part of the <a href="https://systemcrafters.net" target="_blank" class="text-accent-blue hover:text-accent-cyan">System Crafters</a> webring:</p>
</div>
<div class="craftering mt-2 flex items-center justify-center gap-4 text-accent-blue">
<a href="https://craftering.systemcrafters.net/@glenneth/previous" class="hover:text-accent-cyan">Previous</a>
<a href="https://craftering.systemcrafters.net/@glenneth" class="hover:text-accent-cyan">Random</a>
<a href="https://craftering.systemcrafters.net/@glenneth/next" class="hover:text-accent-cyan">Next</a>
</div>
<p class="text-palenight-300 mt-2">
<a href="mailto:glenn@glenneth.org" class="text-accent-blue hover:text-accent-cyan transition-colors">glenn@glenneth.org</a> |
<a href="https://glenneth.org" class="text-accent-blue hover:text-accent-cyan transition-colors">glenneth.org</a>
</p>
</div>
</div>
</footer>
</body>
</html>

View File

@ -6,7 +6,7 @@
<link>https://glenneth.org</link>
<atom:link href="https://glenneth.org/feed.xml" rel="self" type="application/rss+xml" />
<language>en-us</language>
<lastBuildDate>Sat, 08 Mar 2025 10:36:20 GMT</lastBuildDate>
<lastBuildDate>Thu, 13 Mar 2025 04:58:18 GMT</lastBuildDate>
<item>
<title>Aesthetic Meets Ergonomics: My Deep Dive into the Glove80 Keyboard</title>
@ -41,6 +41,88 @@
<category>["personal", "tech", "keyboards", "glove80"]</category>
</item>
<item>
<title>Lessons Learned: One Year with a Custom Static Site Generator</title>
<description>In this post, I'll share the key lessons I've learned and insights I've gained from building and maintaining my own static site generator. While the technical details are interesting, the real value has been in the broader lessons about software development, user experience, and the balance between complexity and simplicity.</description>
<content:encoded><![CDATA[<p>It&#39;s been just over a year since I <a href="/content/posts/2025-01-02-from-haunt-to-custom.html">transitioned from Haunt to my own custom static site generator</a> for this website. What started as an experiment to gain more control over my publishing workflow has evolved into a valuable learning experience that has shaped how I approach web development projects.</p>
<p>In this post, I&#39;ll share the key lessons I&#39;ve learned and insights I&#39;ve gained from building and maintaining my own static site generator. While the technical details are interesting, the real value has been in the broader lessons about software development, user experience, and the balance between complexity and simplicity.</p>
<h2>The Journey of Evolution</h2>
<h3>From Simple Beginnings</h3>
<p>When I first built my static site generator, it was remarkably simple - just the essential features needed to convert my writing into a website. No extra features, no complex configurations, just the basics.</p>
<p>Today, the system has evolved considerably, but not through grand design or elaborate planning. Instead, it grew organically based on real needs and actual usage. This organic growth taught me valuable lessons about software development.</p>
<h3>Lesson 1: Features Should Emerge from Usage</h3>
<p>Many of the features in my static site generator emerged from actual writing and publishing needs:</p>
<ol>
<li><p><strong>The Draft System</strong><br>When I found myself working on multiple posts simultaneously, I needed a way to keep unfinished posts separate from published content. This led to the draft system, which now helps me manage my writing workflow effectively.</p>
</li>
<li><p><strong>Tag Organization</strong><br>As my collection of posts grew, I needed a way to organize related content. The tag system emerged naturally from this need, rather than being built upfront based on assumptions about how I might want to organize content.</p>
</li>
<li><p><strong>Content Validation</strong><br>After accidentally publishing a post with a malformed date and another with a duplicate title, I added validation checks. These weren&#39;t part of the initial design but came from real-world publishing mishaps.</p>
</li>
</ol>
<h3>Lesson 2: Simplicity Drives Performance</h3>
<p>One of the most surprising lessons was how simplicity led to better performance:</p>
<ol>
<li><p><strong>Static HTML Generation</strong><br>By generating plain HTML files, the site loads quickly without any client-side processing. There&#39;s no JavaScript framework, no hydration, and no complex build process - just simple, fast HTML.</p>
</li>
<li><p><strong>Incremental Builds</strong><br>The build system only processes files that have changed. This means that even with hundreds of posts, updates are nearly instantaneous because only the necessary files are rebuilt.</p>
</li>
<li><p><strong>Minimal JavaScript</strong><br>By keeping JavaScript to a minimum and focusing on progressive enhancement, the site remains fast and accessible, even on slower connections.</p>
</li>
</ol>
<h3>Lesson 3: Developer Experience Matters</h3>
<p>A good developer experience has proven crucial for maintaining motivation to write and publish:</p>
<ol>
<li><p><strong>Smart Port Management</strong><br>After encountering port conflicts with other services, I added automatic port detection and fallback. The system now checks if a port is in use and automatically finds the next available one, eliminating the frustration of manual port configuration.</p>
</li>
<li><p><strong>Clear Error Messages</strong><br>When something goes wrong (like a failed CSS build or HTML conversion), the system provides clear, actionable error messages. This immediate feedback helps quickly identify and fix issues during the development process.</p>
</li>
<li><p><strong>Automated Validation</strong><br>The build system validates the environment before starting, checking for required directories and dependencies. These checks catch common setup issues early, making the development process smoother.</p>
</li>
</ol>
<h3>Lesson 4: Content Drives Development</h3>
<p>Perhaps the most important lesson has been letting content needs drive development:</p>
<ol>
<li><p><strong>Markdown Features</strong><br>I only added support for additional Markdown features (like tables and task lists) when I actually needed them in my writing. This prevented feature bloat and kept the system focused.</p>
</li>
<li><p><strong>RSS Feed</strong><br>The RSS feed wasn&#39;t part of the initial design but was added when the content volume grew enough to warrant it. This is a pattern I&#39;ve seen repeatedly - features are most valuable when they solve real, existing needs.</p>
</li>
<li><p><strong>Summary Generation</strong><br>The way post summaries are generated has evolved based on the actual content I write. Initially, it was a simple character count, but it now intelligently extracts meaningful previews based on content structure.</p>
</li>
</ol>
<h2>Looking Forward</h2>
<p>This project has taught me that the best software often evolves gradually in response to real needs rather than being built all at once from a grand design. It&#39;s a lesson that applies well beyond static site generators - it&#39;s about building software that serves actual needs rather than imagined ones.</p>
<p>Just today, while writing this post, I encountered and solved several development workflow issues. Instead of being frustrated by these challenges, I saw them as opportunities to improve the system. The resulting changes - like automatic port detection and better error handling - weren&#39;t part of any grand plan. They emerged naturally from real usage and made the system better in practical, meaningful ways.</p>
<p>The system isn&#39;t perfect, and it probably never will be. But it&#39;s continuously improving in ways that matter for my writing and publishing workflow. That, I&#39;ve learned, is far more valuable than technical perfection.</p>
<p>If you&#39;re considering building your own tools, remember:</p>
<ol>
<li>Start simple and let features emerge from actual usage</li>
<li>Focus on the experience - both for users and developers</li>
<li>Let real needs guide development</li>
<li>Embrace incremental improvements</li>
<li>Value simplicity - it often leads to better performance and maintainability</li>
<li>Use real-world problems as opportunities for improvement</li>
</ol>
<p>These lessons have influenced not just how I approach this project, but how I think about software development in general. Sometimes, the best insights come from the simplest projects - and often, they come right in the middle of writing about them.</p>
<h2>Looking Back and Forward</h2>
<p>Reflecting on this journey, the most valuable insight has been understanding that great software evolves naturally from real needs. Every feature in my static site generator—from the draft system to the validation checks—emerged from actual usage rather than upfront planning.</p>
<p>This experience has fundamentally changed how I approach software development. Instead of trying to build the perfect system from the start, I&#39;ve learned to:</p>
<ol>
<li>Start with the simplest solution that works</li>
<li>Let real usage guide feature development</li>
<li>Focus on maintainability over complexity</li>
<li>Prioritize the developer experience</li>
<li>Keep performance in mind at every step</li>
</ol>
<p>These principles have not only made my static site generator better but have also influenced how I approach every new project. Sometimes the best insights come from the simplest projects, and often they come right in the middle of writing about them.</p>
]]></content:encoded>
<link>https://glenneth.org/content/posts/2025-03-12-lessons-learned-custom-ssg.html</link>
<guid isPermaLink="true">https://glenneth.org/content/posts/2025-03-12-lessons-learned-custom-ssg.html</guid>
<pubDate>Thu, 13 Mar 2025 00:00:00 GMT</pubDate>
<author>Glenn Thompson</author>
<category>[web, development, javascript, static-site, lessons]</category>
</item>
<item>
<title>My Development Environment in 2025: From Editor to Deployment</title>
<description>A comprehensive look at my current development setup in 2025, covering everything from my GNU Guix system foundation to editor configurations, terminal tools, and deployment processes.</description>

View File

@ -60,6 +60,25 @@
<h2 class="text-3xl font-serif font-bold text-accent-yellow mb-8">Blog Posts</h2>
<div class="grid gap-8 md:grid-cols-2">
<article class="bg-base-darker p-6 rounded-lg shadow-lg border border-palenight-400/20 hover:border-accent-purple/40 transition-colors">
<div class="flex flex-wrap items-center gap-2 text-accent-yellow text-sm mb-2 font-bold">
<span>Tech</span>
<span></span><span>web</span><span></span><span>development</span><span></span><span>javascript</span><span></span><span>static-site</span><span></span><span>lessons</span>
<span></span>
<time datetime="2025-03-13">March 13, 2025</time>
</div>
<h3 class="text-xl font-serif font-bold text-accent-yellow mb-3">
<a href="/content/posts/2025-03-12-lessons-learned-custom-ssg.html" class="hover:text-accent-cyan transition-colors">
Lessons Learned: One Year with a Custom Static Site Generator
</a>
</h3>
<p class="text-palenight-100 mb-4">It's been just over a year since I transitioned from Haunt to my own custom static site generator for this website. What started as an experiment to gain more control over my publishing workflow has e...</p>
<div class="flex flex-wrap gap-2">
<span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">web</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">development</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">javascript</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">static-site</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">lessons</span>
</div>
</article>
<article class="bg-base-darker p-6 rounded-lg shadow-lg border border-palenight-400/20 hover:border-accent-purple/40 transition-colors">
<div class="flex flex-wrap items-center gap-2 text-accent-yellow text-sm mb-2 font-bold">
<span>Tech</span>

View File

@ -6,7 +6,7 @@
<link>https://glenneth.org</link>
<atom:link href="https://glenneth.org/feed.xml" rel="self" type="application/rss+xml" />
<language>en-us</language>
<lastBuildDate>Sat, 08 Mar 2025 10:36:20 GMT</lastBuildDate>
<lastBuildDate>Thu, 13 Mar 2025 04:58:18 GMT</lastBuildDate>
<item>
<title>Aesthetic Meets Ergonomics: My Deep Dive into the Glove80 Keyboard</title>
@ -41,6 +41,88 @@
<category>["personal", "tech", "keyboards", "glove80"]</category>
</item>
<item>
<title>Lessons Learned: One Year with a Custom Static Site Generator</title>
<description>In this post, I'll share the key lessons I've learned and insights I've gained from building and maintaining my own static site generator. While the technical details are interesting, the real value has been in the broader lessons about software development, user experience, and the balance between complexity and simplicity.</description>
<content:encoded><![CDATA[<p>It&#39;s been just over a year since I <a href="/content/posts/2025-01-02-from-haunt-to-custom.html">transitioned from Haunt to my own custom static site generator</a> for this website. What started as an experiment to gain more control over my publishing workflow has evolved into a valuable learning experience that has shaped how I approach web development projects.</p>
<p>In this post, I&#39;ll share the key lessons I&#39;ve learned and insights I&#39;ve gained from building and maintaining my own static site generator. While the technical details are interesting, the real value has been in the broader lessons about software development, user experience, and the balance between complexity and simplicity.</p>
<h2>The Journey of Evolution</h2>
<h3>From Simple Beginnings</h3>
<p>When I first built my static site generator, it was remarkably simple - just the essential features needed to convert my writing into a website. No extra features, no complex configurations, just the basics.</p>
<p>Today, the system has evolved considerably, but not through grand design or elaborate planning. Instead, it grew organically based on real needs and actual usage. This organic growth taught me valuable lessons about software development.</p>
<h3>Lesson 1: Features Should Emerge from Usage</h3>
<p>Many of the features in my static site generator emerged from actual writing and publishing needs:</p>
<ol>
<li><p><strong>The Draft System</strong><br>When I found myself working on multiple posts simultaneously, I needed a way to keep unfinished posts separate from published content. This led to the draft system, which now helps me manage my writing workflow effectively.</p>
</li>
<li><p><strong>Tag Organization</strong><br>As my collection of posts grew, I needed a way to organize related content. The tag system emerged naturally from this need, rather than being built upfront based on assumptions about how I might want to organize content.</p>
</li>
<li><p><strong>Content Validation</strong><br>After accidentally publishing a post with a malformed date and another with a duplicate title, I added validation checks. These weren&#39;t part of the initial design but came from real-world publishing mishaps.</p>
</li>
</ol>
<h3>Lesson 2: Simplicity Drives Performance</h3>
<p>One of the most surprising lessons was how simplicity led to better performance:</p>
<ol>
<li><p><strong>Static HTML Generation</strong><br>By generating plain HTML files, the site loads quickly without any client-side processing. There&#39;s no JavaScript framework, no hydration, and no complex build process - just simple, fast HTML.</p>
</li>
<li><p><strong>Incremental Builds</strong><br>The build system only processes files that have changed. This means that even with hundreds of posts, updates are nearly instantaneous because only the necessary files are rebuilt.</p>
</li>
<li><p><strong>Minimal JavaScript</strong><br>By keeping JavaScript to a minimum and focusing on progressive enhancement, the site remains fast and accessible, even on slower connections.</p>
</li>
</ol>
<h3>Lesson 3: Developer Experience Matters</h3>
<p>A good developer experience has proven crucial for maintaining motivation to write and publish:</p>
<ol>
<li><p><strong>Smart Port Management</strong><br>After encountering port conflicts with other services, I added automatic port detection and fallback. The system now checks if a port is in use and automatically finds the next available one, eliminating the frustration of manual port configuration.</p>
</li>
<li><p><strong>Clear Error Messages</strong><br>When something goes wrong (like a failed CSS build or HTML conversion), the system provides clear, actionable error messages. This immediate feedback helps quickly identify and fix issues during the development process.</p>
</li>
<li><p><strong>Automated Validation</strong><br>The build system validates the environment before starting, checking for required directories and dependencies. These checks catch common setup issues early, making the development process smoother.</p>
</li>
</ol>
<h3>Lesson 4: Content Drives Development</h3>
<p>Perhaps the most important lesson has been letting content needs drive development:</p>
<ol>
<li><p><strong>Markdown Features</strong><br>I only added support for additional Markdown features (like tables and task lists) when I actually needed them in my writing. This prevented feature bloat and kept the system focused.</p>
</li>
<li><p><strong>RSS Feed</strong><br>The RSS feed wasn&#39;t part of the initial design but was added when the content volume grew enough to warrant it. This is a pattern I&#39;ve seen repeatedly - features are most valuable when they solve real, existing needs.</p>
</li>
<li><p><strong>Summary Generation</strong><br>The way post summaries are generated has evolved based on the actual content I write. Initially, it was a simple character count, but it now intelligently extracts meaningful previews based on content structure.</p>
</li>
</ol>
<h2>Looking Forward</h2>
<p>This project has taught me that the best software often evolves gradually in response to real needs rather than being built all at once from a grand design. It&#39;s a lesson that applies well beyond static site generators - it&#39;s about building software that serves actual needs rather than imagined ones.</p>
<p>Just today, while writing this post, I encountered and solved several development workflow issues. Instead of being frustrated by these challenges, I saw them as opportunities to improve the system. The resulting changes - like automatic port detection and better error handling - weren&#39;t part of any grand plan. They emerged naturally from real usage and made the system better in practical, meaningful ways.</p>
<p>The system isn&#39;t perfect, and it probably never will be. But it&#39;s continuously improving in ways that matter for my writing and publishing workflow. That, I&#39;ve learned, is far more valuable than technical perfection.</p>
<p>If you&#39;re considering building your own tools, remember:</p>
<ol>
<li>Start simple and let features emerge from actual usage</li>
<li>Focus on the experience - both for users and developers</li>
<li>Let real needs guide development</li>
<li>Embrace incremental improvements</li>
<li>Value simplicity - it often leads to better performance and maintainability</li>
<li>Use real-world problems as opportunities for improvement</li>
</ol>
<p>These lessons have influenced not just how I approach this project, but how I think about software development in general. Sometimes, the best insights come from the simplest projects - and often, they come right in the middle of writing about them.</p>
<h2>Looking Back and Forward</h2>
<p>Reflecting on this journey, the most valuable insight has been understanding that great software evolves naturally from real needs. Every feature in my static site generator—from the draft system to the validation checks—emerged from actual usage rather than upfront planning.</p>
<p>This experience has fundamentally changed how I approach software development. Instead of trying to build the perfect system from the start, I&#39;ve learned to:</p>
<ol>
<li>Start with the simplest solution that works</li>
<li>Let real usage guide feature development</li>
<li>Focus on maintainability over complexity</li>
<li>Prioritize the developer experience</li>
<li>Keep performance in mind at every step</li>
</ol>
<p>These principles have not only made my static site generator better but have also influenced how I approach every new project. Sometimes the best insights come from the simplest projects, and often they come right in the middle of writing about them.</p>
]]></content:encoded>
<link>https://glenneth.org/content/posts/2025-03-12-lessons-learned-custom-ssg.html</link>
<guid isPermaLink="true">https://glenneth.org/content/posts/2025-03-12-lessons-learned-custom-ssg.html</guid>
<pubDate>Thu, 13 Mar 2025 00:00:00 GMT</pubDate>
<author>Glenn Thompson</author>
<category>[web, development, javascript, static-site, lessons]</category>
</item>
<item>
<title>My Development Environment in 2025: From Editor to Deployment</title>
<description>A comprehensive look at my current development setup in 2025, covering everything from my GNU Guix system foundation to editor configurations, terminal tools, and deployment processes.</description>

View File

@ -60,6 +60,25 @@
<h2 class="text-3xl font-serif font-bold text-accent-yellow mb-8">Blog Posts</h2>
<div class="grid gap-8 md:grid-cols-2">
<article class="bg-base-darker p-6 rounded-lg shadow-lg border border-palenight-400/20 hover:border-accent-purple/40 transition-colors">
<div class="flex flex-wrap items-center gap-2 text-accent-yellow text-sm mb-2 font-bold">
<span>Tech</span>
<span></span><span>web</span><span></span><span>development</span><span></span><span>javascript</span><span></span><span>static-site</span><span></span><span>lessons</span>
<span></span>
<time datetime="2025-03-13">March 13, 2025</time>
</div>
<h3 class="text-xl font-serif font-bold text-accent-yellow mb-3">
<a href="/content/posts/2025-03-12-lessons-learned-custom-ssg.html" class="hover:text-accent-cyan transition-colors">
Lessons Learned: One Year with a Custom Static Site Generator
</a>
</h3>
<p class="text-palenight-100 mb-4">It's been just over a year since I transitioned from Haunt to my own custom static site generator for this website. What started as an experiment to gain more control over my publishing workflow has e...</p>
<div class="flex flex-wrap gap-2">
<span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">web</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">development</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">javascript</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">static-site</span><span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">lessons</span>
</div>
</article>
<article class="bg-base-darker p-6 rounded-lg shadow-lg border border-palenight-400/20 hover:border-accent-purple/40 transition-colors">
<div class="flex flex-wrap items-center gap-2 text-accent-yellow text-sm mb-2 font-bold">
<span>Tech</span>

View File

@ -280,7 +280,7 @@ async function updateIndexWithSummaries() {
// Create the HTML for blog posts
const postsHtml = posts.map(post => `
<article class="bg-base-darker p-6 rounded-lg shadow-lg border border-palenight-400/20 hover:border-accent-purple/40 transition-colors">
<div class="flex items-center gap-2 text-accent-yellow text-sm mb-2 font-bold">
<div class="flex flex-wrap items-center gap-2 text-accent-yellow text-sm mb-2 font-bold">
<span>Tech</span>
${post.tags.map(tag => `<span>•</span><span>${tag}</span>`).join('')}
<span></span>
@ -292,7 +292,7 @@ async function updateIndexWithSummaries() {
</a>
</h3>
<p class="text-palenight-100 mb-4">${post.summary}</p>
<div class="flex gap-2">
<div class="flex flex-wrap gap-2">
${post.tags.map(tag => `<span class="text-accent-yellow px-2 py-1 rounded-full bg-base-bg text-xs">${tag}</span>`).join('')}
</div>
</article>