Building My Static Site with a Simple build.js Script

I wanted to keep things lightweight when it comes to building my personal site. My old site was built with vite-press, which is good but I chose it because I was being lazy.

What I like about this approach is, no Webpack, no giant static site generator, just a straightforward build.js script that does everything I need in one go.

Here’s a quick walkthrough of how it works, what it does, and why.

The script’s job is to:

  • Clean the output directory (/public)
  • Copy over all static files (CSS, JS, images, etc...)
  • Convert Markdown posts to HTML with syntax highlighting
  • Generate some additional content (like index pages or side pages) 5. Log the results

Let’s break it down.

Step 1: Reset the Output Folder:

const outputDir = "./public";
if (fs.existsSync(outputDir)) fs.rmSync(outputDir, { recursive: true });
fs.mkdirSync(outputDir, { recursive: true });

Before anything is built, it wipes out the ./public folder to make sure there’s no leftover rubbish from previous builds. Then it recreates it from scratch.

Step 2: Copy Static Assets:

fs.copyFileSync("./static/style.css", path.join(outputDir, "style.css"));
fs.copyFileSync(
  "./static/postStyle.css",
  path.join(outputDir, "postStyle.css")
);
fs.copyFileSync("./static/index.html", path.join(outputDir, "index.html"));
fs.copyFileSync("./static/terminal.js", path.join(outputDir, "terminal.js"));
fs.cpSync("./stls", path.join(outputDir, "stls"), { recursive: true });
fs.cpSync("./images", path.join(outputDir, "images"), { recursive: true });

Here it copies everything that doesn’t need processing, so CSS files, the main index.html, JS, STL files for 3D models, and images.

Step 3: Convert Markdown to HTML

const { marked } = require("marked");
const hljs = require("highlight.js");

marked.setOptions({
  gfm: true,
  breaks: true,
  mangle: false,
  headerIds: false,
  highlight: function (code, lang) {
    if (lang && hljs.getLanguage(lang)) {
      return hljs.highlight(code, { language: lang }).value;
    }
    return hljs.highlightAuto(code).value;
  },
});

This sets up marked (a Markdown parser) with options I like:

  • GitHub-flavored markdown (GFM)
  • Automatic line breaks
  • Syntax highlighting via highlight.js

The highlight function checks if a language is specified and uses it if valid, or falls back to auto-detection.

Step 4: Generate the Content:

const generatePosts = require("./lib/generatePosts");
const generateMisc = require("./lib/generateMisc");

const count = generatePosts(outputDir);
generateMisc(outputDir);

These two modules (generatePosts and generateMisc) handle the actual generation of HTML content from Markdown files and any other extra pages.

The script reports how many posts were generated, which gives a nice success message at the end:

console.log(`✅ Built ${count} posts`);
console.log(`📁 Output in ./public/`);

Why Not Use a Static Site Generator?

Because I don’t need one. This approach:

  • Gives me full control over how files are processed and output
  • Keeps the build process blazingly fast
  • Avoids dependency bloat
  • Makes the structure transparent — I know exactly what’s happening at each step

If I ever want to add more features (RSS, tags, etc.), I just extend the script. :)