npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@beforesemicolon/site-builder

v0.34.0

Published

Site builder based on JSON files

Readme

🚀 BeforeSemicolon Site Builder

npm version License: BSD-3-Clause Build Status

The Next-Generation Website Builder for Developers

BeforeSemicolon Site Builder is a revolutionary JSON-based static site generator that puts developers in complete control. Unlike traditional website builders that lock you into proprietary systems, our builder gives you the power of code with the simplicity of configuration.

🎯 Why Choose BeforeSemicolon Site Builder?

🆚 Traditional Website Builders vs. BeforeSemicolon

| Feature | Traditional Builders | BeforeSemicolon Site Builder | | ------------------------ | ----------------------- | ---------------------------- | | Data Format | Proprietary/Database | Standard JSON files | | Version Control | ❌ Limited/None | ✅ Full Git integration | | Customization | ❌ Template limitations | ✅ Unlimited flexibility | | Performance | ❌ Bloated output | ✅ Optimized static files | | Portability | ❌ Platform locked | ✅ Framework agnostic | | Developer Experience | ❌ GUI only | ✅ Code + Visual | | SEO Control | ❌ Limited | ✅ Complete control | | Build Pipeline | ❌ No control | ✅ Custom build process |

🌟 Key Features

📄 JSON-First Architecture

Define your entire website structure using simple, readable JSON files. No proprietary formats, no vendor lock-in. Templates, widgets, and components are all described in JSON, supporting inheritance, metadata, localization, and more.

🧩 Dynamic Widget System

Create reusable, interactive components with state management and custom logic. Widgets can be defined with inputs, state, and a render function or static content. Widgets support localization, environment variables, and can compose other components.

🏗️ Template Inheritance & Metadata

Templates can extend other templates, allowing for DRY and maintainable site structures. Each template supports rich metadata (SEO, social, custom), scripts, stylesheets, links, fonts, favicons, manifest, CSP, preload, and structured data.

🗂️ Component Library

Build a library of reusable UI components, each with their own styles and content. Components can be referenced and rendered inside widgets and templates.

🌍 Localization Support

Localization files (JSON) are automatically loaded and flattened for use in templates and widgets, enabling multi-language sites out of the box.

Lightning-Fast Build Process

The build script processes templates, widgets, components, assets, and localization files, outputting a fully static, minified site. HTML and CSS are minified, and assets/data are copied to the output directory. Supports production and development modes.

🛠️ Highly Configurable & Extensible

Custom fetchers for widgets/templates, custom components, asset origins, and more. Caching and environment options are available for advanced use cases.

🧑‍💻 TypeScript Native

Strong TypeScript types for templates, widgets, components, styles, and scripts. Input definitions support a wide range of types (text, html, markdown, media, options, groups, lists, etc.).

🚀 Quick Start

Installation

npm install @beforesemicolon/site-builder

Basic Usage

import { buildTemplates, parseTemplate } from '@beforesemicolon/site-builder'

// Build entire site
await buildTemplates({
    srcDir: './src',
    publicDir: './dist',
    prod: true,
})

// Parse individual template
const template = {
    id: 'home',
    name: 'Home Page',
    route: '/',
    type: 'page',
    title: 'Welcome to My Site',
    description: 'An amazing website built with BeforeSemicolon',
    content: [
        {
            name: 'h1',
            children: ['Welcome to {{title}}'],
        },
    ],
}

const html = await parseTemplate(template)

📁 Project Structure

my-website/
├── src/
│   ├── templates/          # Page templates (JSON)
│   │   ├── home.json
│   │   ├── about.json
│   │   └── base.json
│   ├── widgets/            # Dynamic widgets (JS)
│   │   ├── navigation.js
│   │   └── contact-form.js
│   ├── components/         # Static components (JSON)
│   │   ├── hero.json
│   │   └── footer.json
│   ├── stylesheets/        # CSS or other stylesheet files
│   │   └── main.css
│   ├── scripts/            # JavaScript files for the site
│   │   └── app.js
│   ├── assets/             # Static asset/media files (fonts, icons, logo, favicons, etc.)
│   │   ├── fonts/
│   │   ├── icons/
│   │   ├── logo/
│   │   ├── videos/
│   │   ├── audios/
│   │   ├── images/
│   │   └── favicons/
│   │   └── manifest.json
│   │   └── _redirects
│   │   └── robots.txt
│   │   └── sitemap.xml
│   ├── data/               # Static data files (JSON, CSV, etc.)
│   │   └── products.json
│   └── locales/             # Localization files (e.g., en.json, fr.json)
│       ├── en.json
│       └── fr.json
└── public/                   # Generated site

📝 Templates

Templates are the backbone of your site. They define page structure, metadata, and content.

Base Template

{
    "id": "home",
    "name": "Home Page",
    "route": "/",
    "type": "base",
    "lang": "en",
    "title": "My Awesome Website",
    "domain": "https://mysite.com",
    "description": "A site built with BeforeSemicolon Site Builder",
    "metadata": {
        "keywords": ["website", "builder", "static"],
        "themeColor": "#ffffff"
    },
    "stylesheets": ["main.css"],
    "scripts": ["/app.js"],
    "content": [
        {
            "name": "header",
            "class": "site-header",
            "children": [
                {
                    "name": "h1",
                    "children": ["{{title}}"]
                }
            ]
        }
    ]
}

Template Inheritance

{
    "id": "about",
    "extends": "base",
    "type": "page",
    "title": "About Us",
    "route": "/about",
    "content": [
        {
            "name": "main",
            "children": [
                {
                    "name": "h1",
                    "children": ["About {{title}}"]
                }
            ]
        }
    ]
}

🧩 Widgets

Widgets are dynamic, reusable components with logic and state.

// widgets/counter.js
export default {
    id: 'counter',
    name: 'Counter Widget',
    inputs: [
        {
            type: 'number',
            name: 'initialValue',
            value: 0,
            label: 'Initial Value',
        },
    ],
    render: ({ initialValue, env }) => {
        return `
      <div class="counter" data-initial="${initialValue}">
        <button onclick="decrement()">-</button>
        <span class="count">${initialValue}</span>
        <button onclick="increment()">+</button>
      </div>
    `
    },
    scripts: ['widgets/counter-behavior.js'],
}

Using Widgets in Templates

{
    "content": [
        {
            "name": "widget",
            "id": "counter",
            "initialValue": 10
        }
    ],
    "widgetsData": {
        "counter": {
            "initialValue": 5,
            "theme": "dark"
        }
    }
}

🎨 Components

Components are static, reusable UI elements.

{
    "id": "hero",
    "stylesheets": ["components/hero.css"],
    "content": [
        {
            "name": "section",
            "class": "hero",
            "children": [
                {
                    "name": "h1",
                    "class": "hero-title",
                    "children": ["{{title}}"]
                },
                {
                    "name": "p",
                    "class": "hero-subtitle",
                    "children": ["{{subtitle}}"]
                }
            ]
        }
    ]
}

🎯 Advanced Features

Dynamic Content Rendering

import { parseWidget } from '@beforesemicolon/site-builder'

const dynamicContent = await parseWidget({
    node: {
        name: 'widget',
        id: 'product-list',
        category: 'electronics',
    },
    data: { products: await fetchProducts() },
})

Custom Styling

import { parseStyle } from '@beforesemicolon/site-builder'

const styles = parseStyle({
    '.hero': {
        backgroundColor: '#333',
        color: 'white',
        padding: '2rem',
    },
})

Build Optimization

await buildTemplates({
    srcDir: './src',
    publicDir: './dist',
    prod: true, // Enables minification and optimization
})

🔧 Configuration

Parse Options

const options = {
    useCache: true,
    prod: false,
    assetsOrigin: 'https://cdn.mysite.com',
    components: componentLibrary,
    locales: localizationFiles,
    fetchWidget: async (id) => await loadWidget(id),
    fetchTemplate: async (id) => await loadTemplate(id),
}

const html = await parseTemplate(template, options)

Input Definitions

Create rich form inputs for your widgets:

const inputs = [
    {
        type: 'text',
        name: 'title',
        label: 'Page Title',
        value: 'Default Title',
    },
    {
        type: 'options',
        name: 'theme',
        label: 'Color Theme',
        definitions: [
            { name: 'light', value: 'light' },
            { name: 'dark', value: 'dark' },
        ],
    },
    {
        type: 'group',
        name: 'seo',
        label: 'SEO Settings',
        definitions: [
            { type: 'text', name: 'description' },
            { type: 'image', name: 'ogImage' },
        ],
    },
]

🛠️ Development Workflow

Development Server

npm run docs:watch  # Start development server with hot reload

Building for Production

npm run build       # Build optimized production bundle
npm run test        # Run test suite
npm run lint        # Check code quality

Testing

npm test            # Run all tests
npm run test:watch  # Watch mode for development

🌟 Use Cases

🏢 Business Websites

Create professional business sites with dynamic contact forms, product catalogs, and CMS integration.

📝 Blogs & Content Sites

Build SEO-optimized blogs with markdown support, tagging systems, and social sharing.

🛍️ E-commerce

Develop fast, conversion-optimized online stores with dynamic product listings and checkout flows.

📱 Landing Pages

Craft high-converting landing pages with A/B testing capabilities and analytics integration.

🎨 Portfolios

Showcase your work with customizable galleries, case studies, and contact forms.

🚀 Performance Benefits

  • Static Generation: Pre-rendered HTML for maximum speed
  • Code Splitting: Automatic optimization of JavaScript bundles
  • Asset Optimization: Minified CSS/JS and optimized images
  • SEO Ready: Server-side rendering with complete meta control
  • CDN Friendly: Deploy anywhere with zero configuration

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

git clone https://github.com/beforesemicolon/site-builder.git
cd site-builder
npm install
npm run test

📄 License

BSD-3-Clause License - see the LICENSE file for details.

💝 Support


Built with ❤️ by BeforeSemicolon

"The future of web development is declarative, portable, and developer-first."