No release in over 3 years
A Ruby gem for building static HTML sites. Includes generator for creating projects and builder for compiling ERB/Phlex templates to static HTML. Choose your stack: ERB or Phlex, Importmap or ESBuild/Webpack/Vite, TailwindCSS or shadcn, Stimulus or React/Vue/Alpine.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 3.0

Runtime

~> 0.1
~> 13.0
~> 0.23
~> 1.2
 Project Readme

Static Site Builder

Note: This project is currently under active development. Whilst the web setup with TailwindCSS and image handling is fully functional and production-ready, other features may be incomplete or subject to change. Please proceed with caution and report any issues you encounter.

A Ruby-based generator and builder for creating static HTML sites with working JavaScript. No backend required - just compile your templates to static HTML and deploy anywhere.

📖 Learn more: Demo | Project Overview | Getting Started Guide

Why This Exists

Uses ActionView to render ERB templates - get the full flexibility of Rails views (partials, layouts, helpers) compiled to static HTML. Uses standard Ruby gems and familiar patterns.

Why Choose This Over Other Approaches

Better SEO & Search Rankings: Unlike Single Page Applications (SPAs) that rely on client-side JS rendering, static HTML is immediately crawlable by search engines. Your content is fully indexed from the first request, leading to better search rankings and significantly faster page loads.

Simplicity Over Complexity: No need for complex JavaScript frameworks, hydration, or server-side rendering setups. Write Ruby templates that compile to clean, static HTML. Add JavaScript only where you need interactivity, not as a requirement for rendering.

Developer Experience: Work with familiar Rails patterns (ERB, ActionView, partials) without the overhead of a full Rails application. Build fast, deploy anywhere, and maintain easily.

Version Control & Mobile Editing: Your entire site is code in a Git repository. Track changes, collaborate, and edit from anywhere - even your phone with tools like Cursor Agents. No database migrations or CMS interfaces needed. Lightning fast.

Main Objective

Generate static HTML pages with JavaScript files that work. Choose your own stack:

  • Template Engine: ERB or Phlex
  • JavaScript Bundler: Importmap, ESBuild, Webpack, Vite, or none
  • CSS Framework: TailwindCSS, shadcn/ui, or plain CSS
  • JavaScript Framework: Stimulus, React, Vue, Alpine.js, or vanilla JS

Installation

gem install static-site-builder
# or
git clone https://github.com/Ancez/static-site-builder
cd static-site-builder
bundle install

Quick Start

Option 1: Install as a gem

gem install static-site-builder
static-site-builder new my-site

Option 2: Use directly from repo

git clone https://github.com/Ancez/static-site-builder
cd static-site-builder
bundle install
ruby bin/generate my-site

You'll be prompted to choose your stack using an interactive menu with arrow key navigation. Generated sites use:

  • static-site-builder gem for compilation
  • Standard gems (importmap-rails, phlex-rails, etc.) for functionality
  • npm packages for JS bundlers and frameworks

What Gets Generated

A clean project structure that depends on gems:

my-site/
├── Gemfile              # Dependencies (static-site-builder, sitemap_generator, etc.)
├── package.json         # JS dependencies (if needed)
├── Rakefile            # Build tasks (includes sitemap generation)
├── config/
│   ├── importmap.rb    # Importmap config (if using importmap)
│   └── sitemap.rb      # Sitemap generation config
├── app/
│   ├── views/
│   │   ├── layouts/
│   │   ├── pages/
│   │   └── components/     # Reusable components/partials
│   ├── javascript/
│   └── assets/
└── lib/
    ├── site_builder.rb   # Compiles your site
    └── page_helpers.rb   # Page metadata (title, description, etc.)

How It Works

  1. Generator (static-site-generator) - Creates the project structure
  2. Builder Gem (static-site-builder) - Handles ERB/Phlex compilation
  3. Standard Gems - importmap-rails, phlex-rails, etc. for functionality
  4. Build Tools - Rake tasks that use the builder gem

Features

  • 🎯 Static HTML output - No server-side rendering needed
  • 🔧 Flexible stack - Choose what works for you
  • 📦 Gem-based - Uses existing Ruby gems, not custom code
  • 🚀 Fast builds - Compile once, deploy everywhere
  • 🎨 Component support - ERB or Phlex components
  • 📱 Modern JS - ES modules, importmaps, or bundlers

Supported Stacks

Template Engines

  • ERB - Ruby's embedded Ruby templates
  • Phlex - Ruby component library (via phlex-rails gem)

JavaScript Bundlers

  • Importmap - No bundling, use ES modules directly (via importmap-rails gem)
  • ESBuild - Fast JavaScript bundler
  • Webpack - Powerful bundler with plugins
  • Vite - Next-generation frontend tooling
  • None - Vanilla JavaScript, no bundling

CSS Frameworks

  • TailwindCSS - Utility-first CSS framework
  • shadcn/ui - Re-usable components built with Tailwind
  • Plain CSS - Write your own styles

JavaScript Frameworks

  • Stimulus - Modest JavaScript framework
  • React - Popular UI library
  • Vue - Progressive JavaScript framework
  • Alpine.js - Minimal framework for HTML
  • Vanilla JS - No framework

Building Powerful Websites

Using ERB Templates

ERB templates use ActionView - partials, layouts, helpers, and all Rails view features work. Create pages in app/views/pages/:

<h1><%= @title %></h1>
<p><%= @description %></p>
<%= render 'shared/footer' %>

Page metadata is automatically configured in lib/page_helpers.rb (generated automatically):

module PageHelpers
  PAGES = {
    '/' => {
      title: 'My Page',
      description: 'A great page',
      url: 'https://example.com',
      image: 'https://example.com/image.jpg',
      priority: 1.0,
      changefreq: 'weekly'
    }
  }.freeze
end

The builder automatically loads metadata from PageHelpers::PAGES and sets @title, @description, @url, and @image instance variables for use in your templates. This metadata is also used by the sitemap_generator gem for generating sitemaps.

Use layouts in app/views/layouts/application.html.erb:

<!DOCTYPE html>
<html>
<head>
  <title><%= @title || "My Site" %></title>
</head>
<body>
  <%= yield %>
</body>
</html>

Using Phlex Components

Create reusable components in app/views/components/:

class Button < Phlex::HTML
  def initialize(text:, href:, variant: "primary")
    @text = text
    @href = href
    @variant = variant
  end

  def template
    a(href: @href, class: "btn btn-#{@variant}") { @text }
  end
end

Use in pages:

class HomePage < Phlex::HTML
  def template
    div do
      h1 { "Welcome" }
      render Button.new(text: "Get Started", href: "/about")
    end
  end
end

JavaScript with Importmap

No bundling needed - use ES modules directly:

// app/javascript/application.js
import { Application } from "@hotwired/stimulus"
import HelloController from "./controllers/hello_controller"

window.Stimulus = Application.start()
Stimulus.register("hello", HelloController)

JavaScript with Bundlers

Use ESBuild, Webpack, or Vite for modern tooling:

// app/javascript/index.js
import React from 'react'
import { createRoot } from 'react-dom/client'

function App() {
  return <h1>Hello from React!</h1>
}

const root = createRoot(document.getElementById('app'))
root.render(<App />)

CSS with TailwindCSS

Use utility classes directly in templates:

<div class="container mx-auto px-4">
  <h1 class="text-4xl font-bold text-gray-900">Hello World</h1>
</div>

CSS with shadcn/ui

Install components and use them in your templates:

npx shadcn-ui@latest add button

Generating Sitemaps

Sitemap generation is automatically configured when you generate a new site. The sitemap_generator gem is included in the Gemfile, and config/sitemap.rb is automatically created.

The sitemap is generated from your PageHelpers::PAGES metadata during rake build:all. Update config/sitemap.rb to set your domain:

SitemapGenerator::Sitemap.default_host = 'https://yourdomain.com'

The sitemap will be generated in dist/sitemaps/sitemap.xml.gz during the build process.

Examples

ERB + Importmap + Stimulus + TailwindCSS

static-site-builder new my-site
# Choose: ERB, Importmap, TailwindCSS, Stimulus

Phlex + ESBuild + React + shadcn

static-site-builder new my-site
# Choose: Phlex, ESBuild, shadcn/ui, React

Notable Projects

Sites built with Static Site Builder:

Your website? Built with Static Site Builder? Submit a PR to add it here!

Requirements

For Importmap Projects

When using Importmap as your JavaScript bundler:

  1. Install npm dependencies:

    npm install
  2. Build your site - vendor files are automatically copied from node_modules to dist/assets/javascripts/ during the build:

    rake build:all

The build process automatically copies required vendor JavaScript files directly from node_modules to dist/assets/javascripts/ based on your importmap configuration. No intermediate vendor/javascript/ folder is needed.

Development

Running Your Site Locally

After generating a site, you can run it locally with auto-rebuild and live reload:

cd my-site
bundle install
npm install  # Required for importmap projects and JS frameworks

# Start development server (auto-rebuilds on file changes)
rake dev:server

This will:

  • Build your site to dist/
  • Start a web server at http://localhost:3000
  • Watch for file changes and rebuild automatically
  • Auto-refresh your browser when files change

You can change the port with:

PORT=8080 rake dev:server

Building for Production

# Build everything (assets + HTML)
rake build:all

# Or just HTML
rake build:html

# Output is in dist/ directory

Deployment

The dist/ directory contains your complete static site and can be deployed to any static hosting provider.

Cloudflare Pages

  1. Create wrangler.toml in your project root:

    name = 'your-worker-name'
    compatibility_date = '2025-01-22'

    Replace your-worker-name with your desired Worker name (must match your Cloudflare Pages project name).

  2. Connect your repository to Cloudflare Pages in the Cloudflare dashboard

  3. Build settings:

    • Build command: rake build:all
    • Deploy command: npx wrangler deploy --assets=./dist
    • Version command: npx wrangler versions upload
    • Root directory: /
  4. Deploy: Cloudflare Pages will automatically build and deploy on every push to your main branch

Note: Ensure your Gemfile and package.json are properly configured. The build process will install dependencies automatically.

Vercel

  1. Install Vercel CLI (optional):

    npm i -g vercel
  2. Deploy:

    # Build locally first
    bundle install && npm install && bundle exec rake build:all
    
    # Deploy
    vercel --prod

    Or connect your repository in the Vercel dashboard with these settings:

    • Build Command: bundle install && npm install && bundle exec rake build:all
    • Output Directory: dist
    • Install Command: bundle install && npm install
  3. Configuration file (optional vercel.json):

    {
      "buildCommand": "bundle install && npm install && bundle exec rake build:all",
      "outputDirectory": "dist",
      "installCommand": "bundle install && npm install"
    }

Netlify

  1. Create netlify.toml in your project root:

    [build]
      command = "bundle install && npm install && bundle exec rake build:all"
      publish = "dist"
    
    [build.environment]
      RUBY_VERSION = "3.4"
      NODE_VERSION = "24"
  2. Deploy:

    • Connect your repository in Netlify dashboard
    • Netlify will automatically detect netlify.toml and use those settings
    • Or use Netlify CLI: netlify deploy --prod

GitHub Pages

  1. Using GitHub Actions (recommended):

    Create .github/workflows/deploy.yml:

    name: Deploy to GitHub Pages
    
    on:
      push:
        branches: [ main ]
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          
          - name: Set up Ruby
            uses: ruby/setup-ruby@v1
            with:
              ruby-version: 3.4
              bundler-cache: true
          
          - name: Set up Node.js
            uses: actions/setup-node@v4
            with:
              node-version: '24'
              cache: 'npm'
          
          - name: Install dependencies
            run: |
              bundle install
              npm install
          
         - name: Build site
           run: bundle exec rake build:all
           # Note: Vendor files will be automatically copied from node_modules during build
          
          - name: Deploy to GitHub Pages
            uses: peaceiris/actions-gh-pages@v4
            with:
              github_token: ${{ secrets.GITHUB_TOKEN }}
              publish_dir: ./dist
  2. Enable GitHub Pages in your repository settings:

    • Go to Settings → Pages
    • Source: GitHub Actions

Other Static Hosts

For any static hosting provider (AWS S3, Azure Static Web Apps, etc.):

  1. Build locally:

    bundle install
    npm install
    bundle exec rake build:all
  2. Upload dist/ directory to your hosting provider

  3. Configure your host to serve from the dist directory

CI/CD Considerations

  • Vendor files: Vendor files are automatically copied from node_modules to dist/ during build - no vendor folder needed
  • Dependencies: Both Ruby (Gemfile) and Node.js (package.json) dependencies are needed for the build
  • Build order: Install dependencies → Build assets → Build HTML
  • Ruby/Node versions: Specify versions in your CI/CD configuration to ensure consistent builds

Generator Development

# Clone the repo
git clone https://github.com/Ancez/static-site-builder
cd static-site-builder

# Install dependencies
bundle install

# Run tests
bundle exec rspec

# Build the gem
gem build static-site-builder.gemspec

Testing

The project includes comprehensive test coverage:

  • Unit tests for Generator and Builder classes
  • Integration tests for full build workflows
  • End-to-end tests for complete workflows
  • Tests for all stack combinations

Run tests with:

bundle exec rspec

View coverage report:

open coverage/index.html

Architecture

This generator follows the Rails pattern:

  • Generator gem - Creates project structure
  • Builder gem - Handles compilation (separate gem: static-site-builder)
  • Standard gems - Reuse existing Ruby gems
  • Generated code - Minimal, uses gem dependencies

Contributing

Contributions welcome! Especially:

  • New template engine support
  • New bundler integrations
  • New CSS framework setups
  • Documentation improvements

License

MIT