A modern, fast, and secure static site generator built with Swift.
- 🚀 Blazing Fast: Built with Swift for optimal performance with multi-level caching
- 📝 Markdown: Full CommonMark support with frontmatter using Apple's swift-markdown
- 🎨 Templates: Powerful Stencil-based templating engine with custom filters
- 🔄 Live Reload: Development server with automatic rebuilding and real-time error reporting
- 🧩 Built-in Features: Useful capabilities like sitemap/RSS/search/minify are available out of the box
- 💾 Smart Caching: Multi-level intelligent caching for lightning-fast rebuilds
- 📦 Type Safe: Strongly typed configuration and models with comprehensive validation
- ⚡ Simple: Clean, easy-to-use configuration without unnecessary complexity
- 🛡️ Memory Safe: Advanced memory management for WebSocket connections and file watching
git clone https://github.com/SilentMalachite/Hirundo.git
cd hirundo
swift build -c release
cp .build/release/hirundo /usr/local/bin/swift build -c release# Create a new site
hirundo init my-site --blog
# Navigate to your site
cd my-site
# Start the development server
hirundo serveYour site will be available at http://localhost:8080 with live reload enabled.
Create a new Hirundo site.
hirundo init [path] [options]
Options:
--title <title> Site title (default: "My Hirundo Site")
--blog Include blog functionality
--force Force creation in non-empty directoryBuild your static site.
hirundo build [options]
Options:
--config <file> Configuration file path (default: config.yaml)
--environment <env> Build environment (default: production)
--drafts Include draft posts
--clean Clean output before building
--continue-on-error Continue building even if some files fail (error recovery mode)
--verbose Show verbose error informationStart the development server with live reload.
hirundo serve [options]
Options:
--port <port> Server port (default: 8080)
--host <host> Server host (default: localhost)
--no-reload Disable live reload
--no-browser Don't open browser automatically
--verbose Show verbose error informationCreate new content.
# Create a new blog post
hirundo new post "My Post Title" --tags "swift,web" --categories "development"
# Create a new page
hirundo new page "About Us" --layout "default"Clean output directory and caches.
hirundo clean [options]
Options:
--cache Also clean asset cache
--force Skip confirmationmy-site/
├── config.yaml # Site configuration
├── content/ # Markdown content
│ ├── index.md # Home page
│ ├── about.md # About page
│ └── posts/ # Blog posts
├── templates/ # HTML templates
│ ├── base.html # Base layout
│ ├── default.html # Default page template
│ └── post.html # Blog post template
├── static/ # Static assets
│ ├── css/ # Stylesheets
│ ├── js/ # JavaScript
│ └── images/ # Images
└── _site/ # Generated output (git ignored)
site:
title: "My Site"
description: "A site built with Hirundo"
url: "https://example.com"
language: "en-US"
author:
name: "Your Name"
email: "your.email@example.com"
build:
contentDirectory: "content"
outputDirectory: "_site"
staticDirectory: "static"
templatesDirectory: "templates"
server:
port: 8080
liveReload: true
blog:
postsPerPage: 10
generateArchive: true
generateCategories: true
generateTags: true
rssEnabled: true
# Performance limits (optional)
limits:
maxMarkdownFileSize: 10485760 # 10MB
maxConfigFileSize: 1048576 # 1MB
maxFrontMatterSize: 100000 # 100KB
maxFilenameLength: 255
maxTitleLength: 200
maxDescriptionLength: 500
# Features (optional)
features:
sitemap: true
rss: true
searchIndex: true
minify: true
Hirundo supports YAML frontmatter in your Markdown files:
---
title: "My Post Title"
date: 2024-01-15T10:00:00Z
layout: "post"
categories: ["development", "swift"]
tags: ["static-site", "web"]
draft: false
---
# My Post Title
Your content here...Hirundo uses the Stencil templating engine. Templates have access to these variables:
site: Site configuration and metadatapage: Current page datapages: All pagesposts: All blog postscategories: Category mappingstags: Tag mappingscontent: Rendered page content
date: Format datesslugify: Create URL slugsexcerpt: Extract excerptsabsolute_url: Create absolute URLsmarkdown: Render Markdown
{% extends "base.html" %}
{% block content %}
<article>
<h1>{{ page.title }}</h1>
{% if page.date %}
<time>{{ page.date | date: "%B %d, %Y" }}</time>
{% endif %}
{{ content }}
</article>
{% endblock %}Hirundo provides built-in features. Dynamic loading of external code is not supported for security and simplicity.
Generates sitemap.xml for search engines.
Creates rss.xml for your blog posts.
Minifies CSS/JS assets for better performance.
Generates a search index for client-side search functionality.
Hirundo implements appropriate security measures for a static site generator:
- File Size Limits: Configurable limits for markdown files and frontmatter
- Path Validation: Standard path traversal protection
- Content Processing: Safe processing of user-generated content
- CSS/JS Processing: Standard processing with minification support
- Path Sanitization: Basic path cleaning and validation
- WebSocket Management: Clean WebSocket connection handling
- Live Reload: Simple file watching with automatic cleanup
- Error Handling: Secure error reporting
You can quickly verify end-to-end using the provided fixture:
cd test-hirundo
swift run --package-path .. hirundo build --clean
swift run --package-path .. hirundo serve
# open http://localhost:8080 and edit files under test-hirundo/content/- Swift 6.0+
- macOS 12+
- Xcode 16+ (for macOS development)
git clone https://github.com/SilentMalachite/Hirundo.git
cd hirundo
swift buildswift test- Development Guide: see
DEVELOPMENT.md - Testing Guide: see
TESTING.md - Architecture: see
ARCHITECTURE.md - Security Policy and guidance: see
SECURITY.mdandWEBSOCKET_AUTHENTICATION.md - Contributing Guide: see
CONTRIBUTING.md - 日本語ドキュメント:
README.ja.md
Hirundo includes a test suite that covers core functionality:
- Unit Tests: Individual component testing
- Integration Tests: End-to-end workflow validation
- Edge Case Tests: Error handling and edge case scenarios
AssetPipelineTests- Asset processing and minificationConfigTests- Configuration validation and parsingContentProcessorTests- Markdown processing and validationEdgeCaseTests- Error handling and edge case scenariosIntegrationTests- End-to-end functionalityHotReloadManagerTests- File watching functionality
All tests are expected to pass. Run swift test to verify on your environment.
Set the log level for detailed output:
HIRUNDO_LOG_LEVEL=debug hirundo build- swift-markdown: Apple's CommonMark parser
- Stencil: Template engine
- Yams: YAML parser
- Swifter: Lightweight HTTP server
- swift-argument-parser: Command-line interface
- Multi-level Caching: Parsed content, rendered pages, and template caching
- Async/Await: Parallel processing for improved build times
- Streaming: Efficient memory usage for large sites
- Memory Management: Clean resource management and file handle handling
- Hot Reload: File system monitoring with automatic cleanup
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite
- Submit a pull request
Hirundo is released under the MIT License. See LICENSE for details.
- Built with Swift
- Inspired by modern static site generators
- Uses Apple's swift-markdown for reliable Markdown parsing
Made with ❤️ and Swift