Fast static site generator with built-in HTTP server
Turn any folder of Markdown into a website — instantly. Zero config.
thypress serve # Live server with hot reload (11k req/s)
thypress build # Static site output for any CDNZero configuration. Zero complexity. Zero excuses.
THYPRESS is a static site generator that's also an HTTP server.
Drop a folder of .md, .txt, or .html files into it → get a website with:
- 11,209 req/s dev server (benchmarked)
- Built-in image optimization (WebP + responsive sizes)
- Zero configuration (really, just drag & drop)
- Server mode OR static build output
- 7 dependencies (not 1,000+)
Who is this for?
- Writers who hate build tools
- Developers who want speed without complexity
- Anyone publishing docs, blogs, portfolios, or knowledge bases
- Teams that need Git-based publishing without a CMS
What makes it different?
- Dual-mode: Serve live from a VPS OR build static files for a CDN
- Content-first: Your folder structure = your site structure
- HTML-aware: Detects complete HTML docs vs fragments
- Fast by design: Pre-rendering + pre-compression = 11k req/s
v0.2.0 - Early release. Here's where it stands:
✅ Ready for:
- Personal blogs and portfolios
- Side projects and experiments
- Documentation sites
- Learning and teaching
- Prototypes and MVPs
- Company blogs (new project, single maintainer)
- Client work (explain limitations first)
- Business-critical sites (no SLA, no commercial support)
❌ Not ready for:
- Enterprise (wait for v1.0+)
- High-traffic production (needs more testing)
- Regulated industries (no security audit yet)
Stability: The core is solid. The ecosystem is young.
macOS / Linux:
curl -sSL https://thypress.org/install.sh | bashWindows (PowerShell):
iwr https://thypress.org/install.ps1 | iexManual: Download binary from GitHub Releases
mkdir my-blog && cd my-blog
thypress serveThat's it. Your site is live at http://localhost:3009.
THYPRESS auto-creates:
content/posts/2024-01-01-welcome.md(example post)templates/my-press/(your theme folder)config.json(site configuration)
echo "# Hello World" > content/posts/hello.mdThe page appears instantly. No restart needed.
# Option A: Static hosting (Netlify, Vercel, GitHub Pages)
thypress build
# Upload the /build folder
# Option B: Server mode (VPS, Railway, Raspberry Pi)
thypress build --serve
# HTTP server now running on port 3009Done. You have a website.
- Installation
- Usage
- Content Structure
- Features
- Configuration
- Theming
- Deployment
- Performance
- Architecture
- Comparison
- Troubleshooting
- Contributing
- FAQ
- Roadmap
- License
macOS / Linux:
curl -sSL https://thypress.org/install.sh | bashThis script:
- Detects your OS and architecture
- Downloads the latest binary from GitHub releases
- Makes it executable
- Installs to
/usr/local/bin/thypress(or current directory if no sudo)
Windows (PowerShell as Administrator):
iwr https://thypress.org/install.ps1 | iexVerify installation:
thypress version
# THYPRESS v0.2.0-
Download the binary for your OS from GitHub Releases:
thypress-linux-x64(Linux)thypress-macos-arm64(Apple Silicon)thypress-macos-x64(Intel Mac)thypress-windows-x64.exe(Windows)
-
Make it executable (Unix only):
chmod +x thypress
-
Move to PATH (optional but recommended):
# macOS / Linux sudo mv thypress /usr/local/bin/ # Windows: Add to PATH or run from current directory
-
Run it:
thypress --help
Requirements:
- Bun v1.0+
Steps:
# Clone the repository
git clone https://github.com/thypress/binder.git
cd binder
# Install dependencies (7 packages)
bun install
# Run from source
bun src/cli.js serve
# Or build a binary
bun build src/cli.js --compile --outfile thypressDependencies (only 7):
feed- RSS generationgray-matter- Front matter parsinghandlebars- Templatinghighlight.js- Syntax highlightinghtmlparser2- HTML parsingmarkdown-it+ plugins - Markdown renderingsharp- Image optimizationsitemap- Sitemap generation
thypress # Start dev server (default)
thypress serve # Start dev server (alias: s, dev)
thypress build # Build static site (alias: b)
thypress build --serve # Build + preview with HTTP server
thypress clean # Delete .cache directory
thypress version # Show version (alias: -v, --version)
thypress help # Show help (alias: -h, --help)--dir <path> # Target directory (default: current)
-d <path> # Short form of --dir
--no-browser # Don't auto-open browser
--no-open # Alias for --no-browser
--serve # Serve after building (for 'build' command)
[directory] # Direct path (e.g., thypress my-blog/)Basic usage:
# Serve current directory
thypress
# Serve a specific directory
thypress my-blog/
thypress --dir ~/projects/blog
# Build static output
thypress build
# Build and preview
thypress build --serve
# Clean image cache
thypress cleanProduction deployment:
# Build static files for CDN
thypress build
# Output in ./build/
# OR run as HTTP server
thypress build --serve --no-browser
# Production server on port 3009Development workflow:
# Terminal 1: Watch and serve
thypress serve
# Terminal 2: Edit content
echo "# New Post" > content/posts/new.md
# Server detects change and re-rendersTHYPRESS automatically detects your content structure:
my-blog/
├── content/ ← Detected: creates structured site
│ ├── posts/ → Blog posts
│ │ ├── 2024-01-01-welcome.md
│ │ └── 2024-01-15-second-post.md
│ ├── docs/ → Documentation
│ │ ├── getting-started.md
│ │ └── api/
│ │ └── reference.md
│ └── about.md → Static page
├── templates/ ← Themes
│ └── my-press/
│ ├── index.html
│ ├── post.html
│ └── style.css
└── config.json ← Site configuration
URLs generated:
content/posts/2024-01-01-welcome.md→/posts/2024-01-01-welcome/content/docs/getting-started.md→/docs/getting-started/content/about.md→/about/
Navigation: Auto-generated from folder structure.
my-blog/
├── posts/ ← Detected: creates flat blog
│ ├── 2024-01-01-welcome.md
│ └── 2024-01-15-second.md
├── templates/
└── config.json
URLs generated:
posts/2024-01-01-welcome.md→/2024-01-01-welcome/
Best for: Simple blogs migrated from v0.1.
my-notes/
├── index.md ← Detected: serves root files
├── about.md
├── projects.md
└── config.json
URLs generated:
index.md→/about.md→/about/
Best for: Personal wikis, note collections, minimal sites.
THYPRESS supports three content types:
---
title: My Post
date: 2024-01-01
tags: [blog, tech]
---
# My Post
Content here.Features:
- Full CommonMark + GFM support
- Syntax highlighting (140+ languages)
- Automatic
<picture>tags for images - Auto-generated heading IDs
- Table of contents ready
Just plain text.
No formatting needed.
Rendered as:
<pre>Just plain text.
No formatting needed.</pre>Best for: ASCII art, logs, simple notes.
THYPRESS detects HTML intent:
Complete Document (served raw, no template):
<!DOCTYPE html>
<html>
<head>
<title>Custom Page</title>
</head>
<body>
<h1>I control everything</h1>
</body>
</html>Fragment (wrapped in template):
<h1>My Content</h1>
<p>This will be wrapped in post.html template.</p>Force raw output:
---
template: none
---
<!DOCTYPE html>
<html>...</html>Force templated output:
---
template: post
---
<h1>Fragment</h1>
<p>Even though this looks complete, wrap it.</p>Optional YAML metadata at the top of files:
---
title: "Post Title" # Optional: auto-detected from H1 or filename
date: 2024-01-01 # Optional: auto-detected from filename or file date
createdAt: 2024-01-01 # Alias for 'date'
updatedAt: 2024-01-15 # Optional: defaults to file modification time
tags: [blog, tech, tutorial] # Optional: used for tag pages
description: "Short summary" # Optional: for meta description and excerpts
template: custom # Optional: use templates/{theme}/custom.html
image: /images/og-image.jpg # Optional: OpenGraph image (auto from first image)
author: "Author Name" # Optional: defaults to config.json author
---Minimal example (all auto-detected):
# My Post Title
Content here.THYPRESS extracts:
- Title: From
# H1heading or filename - Date: From
YYYY-MM-DD-filename prefix or file creation date - Updated: From file modification time
- OG Image: From first image in content
Rules:
- Remove file extension (
.md,.txt,.html) - Remove
indexfrom path end - Add leading
/and trailing/ - Preserve folder structure
Examples:
| File Path | URL |
|---|---|
content/posts/hello.md |
/posts/hello/ |
content/about.md |
/about/ |
content/docs/api/auth.md |
/docs/api/auth/ |
content/index.md |
/ |
posts/2024-01-01-welcome.md |
/2024-01-01-welcome/ (legacy mode) |
Date prefixes are preserved in URLs (unlike Jekyll).
Automatic WebP + JPEG generation with responsive sizes.
When you reference an image in Markdown:
THYPRESS automatically:
- Reads the original image and determines its width
- Generates responsive sizes: 400w, 800w, 1200w (or smaller if original is smaller)
- Creates two formats: WebP (modern) + JPEG (fallback)
- Caches in
.cache/with MD5 hash (persistent across builds) - Outputs
<picture>tag:
<picture>
<source
srcset="/posts/photo-400-abc123.webp 400w, /posts/photo-800-abc123.webp 800w, /posts/photo-1200-abc123.webp 1200w"
type="image/webp"
sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px">
<source
srcset="/posts/photo-400-abc123.jpg 400w, /posts/photo-800-abc123.jpg 800w, /posts/photo-1200-abc123.jpg 1200w"
type="image/jpeg"
sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px">
<img
src="/posts/photo-800-abc123.jpg"
alt="Alt text"
loading="lazy"
decoding="async">
</picture>Absolute (from content root):
Resolves to: content/images/logo.png
Relative to post directory:

Resolves relative to the post's location.
Relative without ./:
Resolves relative to post directory.
- Parallel processing: Uses 75% of CPU cores
- Persistent cache:
.cache/survives rebuilds - Cache cleanup: Removes orphaned files automatically
- Build time: ~45 seconds for 50 images (6 files per image = 300 files)
Client-side search with MiniSearch.
- No backend required: Pure JavaScript, works offline
- Fast: Fuzzy search with prefix matching
- Smart ranking: Title > description > content
- Auto-indexed: Generated at build time
- Build generates
/search.json:
[
{
"id": "post-slug",
"title": "Post Title",
"slug": "post-slug",
"url": "/posts/post-slug/",
"date": "2024-01-01",
"tags": ["blog"],
"description": "Short description",
"content": "First 5000 chars of content..."
}
]- Template includes search UI (in default theme):
<input type="text" id="search" placeholder="Search posts..." />
<div id="search-results"></div>
<script src="https://cdn.jsdelivr.net/npm/minisearch@7.1.0/dist/umd/index.min.js"></script>
<script>
// MiniSearch initialization in templates/.default/index.html
</script>- Users type → instant results
Automatic tag pages at /tag/{tagname}/.
Add tags to front matter:
---
tags: [blog, tutorial, javascript]
---THYPRESS automatically:
- Creates tag pages:
/tag/blog/,/tag/tutorial/,/tag/javascript/ - Lists tagged posts sorted by date (newest first)
- Generates tag clouds (if your theme supports it)
Tag pages use templates/{theme}/tag.html:
Automatic pagination for the homepage.
Default: 10 posts per page (defined in src/renderer.js).
URLs generated:
- Page 1:
/ - Page 2:
/page/2/ - Page 3:
/page/3/ - ...
Homepage gets a pagination object:
Auto-generated feeds for SEO and syndication.
Generated automatically with:
- Last 20 posts
- Full content or description
- Pub date, updated date
- Tags as categories
- Proper Dublin Core metadata
Link in template:
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/rss.xml">Generated automatically with:
- All content pages
- Tag pages
- Homepage
- Priority and change frequency
Linked in robots.txt:
User-agent: *
Allow: /
Sitemap: https://example.com/sitemap.xml
Auto-generated from folder structure (structured mode only).
Your folder structure:
content/
├── posts/
│ ├── 2024-01-01-first.md
│ └── 2024-01-15-second.md
├── docs/
│ ├── intro.md
│ └── api/
│ ├── auth.md
│ └── users.md
└── about.md
Becomes navigation with nested <details> tags.
Note: navigation is only available in structured mode (content/ with sections).
Production-ready SEO out of the box.
Every page includes:
- Title tags
- Meta descriptions
- Open Graph tags (Facebook)
- Twitter cards
- JSON-LD structured data
- Canonical URLs
Generated files:
robots.txt(templated with your site URL)llms.txt(for AI crawlers)404.html(custom error page)sitemap.xmlrss.xml
Automatic code highlighting with highlight.js.
140+ languages including JavaScript, Python, Ruby, Go, Rust, HTML, CSS, Bash, SQL, and more.
```javascript
function hello(name) {
console.log(`Hello, ${name}!`);
}
```Change theme by editing templates/{theme}/post.html:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css">Available themes: highlight.js demo
Location: config.json in project root
Full example:
{
"title": "My Site",
"description": "A site powered by THYPRESS",
"url": "https://example.com",
"author": "Your Name",
"theme": "my-press",
"index": "custom-homepage-slug"
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
title |
string | No | "My Site" |
Site name (used in title tags, RSS, etc.) |
description |
string | No | "A site powered by THYPRESS" |
Site description (meta tags) |
url |
string | No | "https://example.com" |
Production URL (for absolute URLs) |
author |
string | No | "Anonymous" |
Default author (overridable per post) |
theme |
string | No | First in templates/ |
Theme folder name (e.g., "my-press") |
index |
string | No | null |
Custom homepage slug (e.g., "welcome" uses /welcome/ as /) |
THYPRESS works with an empty config:
{}Complete list of supported front matter fields:
---
# Content Metadata
title: "Post Title" # Post title (auto from H1 or filename)
date: 2024-01-01 # Publication date (auto from filename/file)
createdAt: 2024-01-01 # Alias for 'date'
updatedAt: 2024-01-15 # Last updated (auto from mtime)
description: "Short summary" # Meta description & excerpt
# Taxonomy
tags: [blog, tech] # Tags (creates /tag/{tag}/ pages)
author: "Author Name" # Author (overrides config.json)
# SEO & Social
image: /path/to/og-image.jpg # OpenGraph image (auto from first image)
# Template Control
template: custom # Use templates/{theme}/custom.html
# OR 'none' to serve raw HTML
# Custom Fields (available in templates)
customField: "Any value" # Access via {{frontMatter.customField}}
---Title extraction (priority order):
- Front matter
title: "..." - First
# H1heading in content - Filename without date prefix and extension
- Raw filename
Date extraction (priority order):
- Front matter
date:orcreatedAt: - Filename prefix
YYYY-MM-DD- - File birth time (if valid)
- File modification time
Updated date:
- Front matter
updatedAt:orupdated: - File modification time
OpenGraph image:
- Front matter
image: - First image referenced in content (auto-detected)
Theme location: templates/{theme-name}/
Required files (minimum):
templates/my-theme/
├── index.html # Homepage (list of posts)
├── post.html # Individual post/page
└── tag.html # Tag archive page
Optional files:
templates/my-theme/
├── style.css # Styles (served at /assets/style.css)
├── script.js # JavaScript (served at /assets/script.js)
├── robots.txt # Templated robots.txt
├── llms.txt # Templated llms.txt
├── 404.html # Custom 404 page
└── {section}.html # Section-specific template (e.g., docs.html)
Asset handling:
- Files in
templates/{theme}/(except.html) →/assets/ - Files can include Handlebars templates (e.g.,
{{siteUrl}}) - Subdirectories preserved:
templates/my-theme/fonts/→/assets/fonts/
Available in all templates:
Built-in helpers:
Step 1: Copy default theme
cp -r templates/.default/ templates/my-theme/Step 2: Edit templates
nano templates/my-theme/index.html
nano templates/my-theme/style.cssStep 3: Activate theme
// config.json
{
"theme": "my-theme"
}Step 4: Restart server
thypress serveBest for: Most use cases (CDN-backed, fast, cheap/free)
thypress buildCreates:
build/
├── index.html # Homepage
├── posts/
│ └── welcome/
│ └── index.html # Post pages
├── tag/
│ └── blog/
│ └── index.html # Tag pages
├── assets/
│ ├── style.css # Theme assets
│ └── script.js
├── images/
│ ├── photo-400-abc123.webp # Optimized images
│ └── ...
├── rss.xml # RSS feed
├── sitemap.xml # Sitemap
├── search.json # Search index
├── robots.txt # SEO
├── llms.txt # AI crawlers
└── 404.html # Error page
Option 1: Drag & Drop
thypress build
# Drag /build folder to Netlify dashboardOption 2: Git-based
Create netlify.toml:
[build]
command = "curl -sSL https://thypress.org/install.sh | bash && thypress build"
publish = "build"Create vercel.json:
{
"buildCommand": "curl -sSL https://thypress.org/install.sh | bash && thypress build",
"outputDirectory": "build"
}Create .github/workflows/deploy.yml:
name: Deploy to GitHub Pages
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install THYPRESS
run: curl -sSL https://thypress.org/install.sh | bash
- name: Build site
run: thypress build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./buildBest for: Self-hosting on VPS, Raspberry Pi, or when you need dynamic features
thypress serveFeatures:
- Hot reload (<50ms)
- File watching
- Image optimization on save
- Admin panel at
/__thypress/
Not recommended for production (no process management, single instance).
thypress build --serveFeatures:
- Pre-rendered pages (11k req/s)
- Pre-compressed (Brotli + gzip)
- ETag caching (304 responses)
- Admin panel (
/__thypress/)
Port: 3009 (auto-finds available if busy)
Note: For production, add:
- Process management (systemd/PM2)
- HTTPS (reverse proxy with Caddy/nginx)
- Monitoring
Create /etc/systemd/system/thypress.service:
[Unit]
Description=THYPRESS Blog Server
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/myblog
ExecStart=/usr/local/bin/thypress build --serve --no-browser
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable thypress
sudo systemctl start thypress/etc/caddy/Caddyfile:
blog.example.com {
reverse_proxy localhost:3009
encode gzip
}
Restart Caddy:
sudo systemctl restart caddyDone. HTTPS + caching handled by Caddy.
Dockerfile:
FROM oven/bun:1
WORKDIR /app
# Copy content
COPY content/ content/
COPY templates/ templates/
COPY config.json config.json
# Install THYPRESS
RUN curl -sSL https://thypress.org/install.sh | bash
# Build site
RUN thypress build
# Serve
EXPOSE 3009
CMD ["thypress", "build", "--serve", "--no-browser"]Build and run:
docker build -t my-blog .
docker run -p 3009:3009 my-blog# SSH into Pi
ssh pi@raspberrypi.local
# Install THYPRESS
curl -sSL https://thypress.org/install.sh | bash
# Create site
mkdir ~/blog && cd ~/blog
thypress serveRun as service (see systemd section above).
Test environment:
- Dell XPS 9380, i7 8th Gen, 16GB RAM
- 100-page blog with images
- Single content page request
Dev Server Performance:
| Metric | THYPRESS | Hugo | Jekyll | Eleventy | Gatsby |
|---|---|---|---|---|---|
| Requests/sec | 11,209 | 6,500 | 280 | 2,800 | 1,200 |
| Latency (avg) | 0.25ms | 0.5ms | 15ms | 2ms | 4ms |
| Memory | 120MB | 80MB | 200MB | 150MB | 800MB |
Build Performance:
| Pages | THYPRESS | Hugo | Jekyll | Eleventy | Gatsby |
|---|---|---|---|---|---|
| 100 | 3s | 1s | 45s | 12s | 60s |
| 1,000 | 30s | 5s | 8min | 2min | 10min |
Image Optimization:
| Metric | Value |
|---|---|
| 50 images | 45s (300 files generated) |
| Formats | WebP + JPEG |
| Sizes per image | 3 (400w, 800w, 1200w) |
| Cache hit rate | 100% after first build |
| Parallel workers | 75% of CPU cores |
The .cache/ directory stores optimized images. Keep it in production:
# .gitignore
.cache/
build/
node_modules/Always use thypress build --serve in production (not thypress serve):
# Bad (development server)
thypress serve
# Good (pre-rendered, pre-compressed)
thypress build --servePerformance difference:
serve: ~3,000 req/s (renders on demand)build --serve: ~11,000 req/s (pre-rendered)
Default: 10 posts/page. Edit src/renderer.js if building from source:
export const POSTS_PER_PAGE = 20;1. Pre-compressed Cache (fastest):
- Stores Brotli + gzip versions
- Used by:
thypress build --serve - Hit rate: ~98%
- Response time: ~0.2ms
2. Rendered Cache:
- Stores rendered HTML
- Used by: Both modes
- Hit rate: ~95%
- Response time: ~0.5ms (needs compression)
3. Dynamic Cache:
- Stores
search.json,rss.xml,sitemap.xml - Hit rate: 100% (until invalidated)
File changes → Invalidate all caches and re-render.
Manual cache clear:
# Via admin panel
curl -X POST http://localhost:3009/__thypress/clear-cacheloadAllContent()
→ Scan content directory recursively
→ For each .md/.txt/.html file:
- Parse front matter (gray-matter)
- Process content (markdown-it or wrap in <pre>)
- Extract metadata (title, date, tags)
- Detect images → build reference list
- Store in contentCache
→ Build navigation tree from folders
→ Return {contentCache, navigation, imageReferences}
loadTheme()
→ Load embedded .default templates
→ Find active theme (config.json or first in templates/)
→ Load theme templates (compile with Handlebars)
→ Load theme assets (CSS, JS, etc.)
→ Return {templatesCache, themeAssets}
preRenderAllContent()
→ For each content item:
- Select template (by front matter, section, or default)
- Render with Handlebars (pass all variables)
- Store in renderedCache
→ Render index pages (pagination)
→ Render tag pages
→ Result: renderedCache with ~150 pages
preCompressContent()
→ For each rendered page:
- Generate ETag (MD5 hash)
- Compress with gzip → store
- Compress with Brotli → store
→ Result: precompressedCache with ~300 entries (150 pages × 2 formats)
GET /posts/welcome/
→ Check pre-compressed cache
- Accept-Encoding: br or gzip?
- If-None-Match: ETag match? → 304
- Return compressed content
→ If cache miss:
- Render on demand
- Compress on demand
- Return with ETag
optimizeImagesFromContent()
→ Deduplicate images by path
→ Check if optimization needed (compare mtimes)
→ Parallel optimization (75% CPU cores):
- sharp(image).resize(400).webp() → file
- sharp(image).resize(400).jpeg() → file
- Repeat for 800w, 1200w
→ Result: .cache/ with 6 files per image
watch(contentRoot)
→ On file change:
- Content file? → Reload + re-render + re-compress
- Image file? → Schedule optimization (debounced)
- Template file? → Reload theme + re-render all
→ On file delete:
- Remove from caches
- Rebuild navigation
URL: http://localhost:3009/__thypress/
Dashboard:
- Content files count
- Operating mode (structured/legacy/simple)
- Content root path
- Active theme
- Pre-rendered pages count
- Pre-compressed entries count
- Images cached count
- Static cache size
- HTML file mode detection
Build Button:
- Triggers
thypress buildvia API - Shows progress
- Displays result
Clear Cache Button:
- Clears all caches
- Frees memory
- Re-renders on next request
Trigger Build:
curl -X POST http://localhost:3009/__thypress/build{
"success": true,
"message": "Build complete"
}Clear Cache:
curl -X POST http://localhost:3009/__thypress/clear-cache{
"success": true,
"freed": 450
}Watched paths:
content/(orposts/in legacy mode)templates/config.json
Events:
change- File modifiedrename- File created or deleted
Debouncing:
- Image optimization: 500ms debounce
Performance:
- Hot reload: <50ms
- Image optimization: Background task (doesn't block)
| Feature | THYPRESS | Hugo |
|---|---|---|
| Language | JavaScript (Bun) | Go |
| Setup | Zero config | Requires config.toml |
| Templates | Handlebars | Go templates |
| Dev Server | 11k req/s | 6k req/s |
| Build Speed | 30s (1000 pages) | 5s ⭐ |
| Images | Built-in | Requires Hugo Pipes |
| Search | Built-in | External |
| Production Server | ✅ Built-in | ❌ Build only |
| Best For | Flexibility, speed, simplicity | Maximum build speed at scale |
Choose THYPRESS if: You want simplicity and a production server.
Choose Hugo if: You're building 10,000+ pages and need sub-5s builds.
| Feature | THYPRESS | Jekyll |
|---|---|---|
| Language | JavaScript (Bun) | Ruby |
| Dev Server | 11k req/s | 280 req/s |
| Build Speed | 30s (1000 pages) | 8 minutes |
| Images | Built-in | Plugins required |
| Production Server | ✅ Built-in | ❌ Build only |
| Install | One binary | Gem dependencies |
| Best For | Speed, simplicity | GitHub Pages integration |
Choose THYPRESS if: You want speed.
Choose Jekyll if: You're locked into GitHub Pages.
| Feature | THYPRESS | Gatsby |
|---|---|---|
| Setup | Zero config | Complex GraphQL |
| Dev Server | 11k req/s | 1.2k req/s |
| Output Size | 2 MB (100 pages) | 12 MB + React |
| Dependencies | 7 | 1000+ |
| Best For | Simplicity | Complex React apps |
Choose THYPRESS if: You just want a blog/docs site.
Choose Gatsby if: You're building a React app.
| Feature | THYPRESS | Eleventy |
|---|---|---|
| Dev Server | 11k req/s | 2.8k req/s |
| Build Speed | 30s (1000 pages) | 2 minutes |
| Images | Built-in | Plugins required |
| Production Server | ✅ Built-in | ❌ Build only |
| Templates | Handlebars only | Any (10+ engines) |
Choose THYPRESS if: You want speed.
Choose Eleventy if: You want maximum flexibility.
THYPRESS auto-finds the next available port (3009-3108).
Manual fix:
lsof -i :3009
kill -9 <PID>Solutions:
- Check image paths (must be relative or absolute from content root)
- Check file permissions:
chmod 644 content/**/*.jpg - Force rebuild:
thypress clean && thypress build
Check:
- Template exists:
ls templates/my-press/custom.html - Front matter:
template: custom - Theme is active in config.json
Server doesn't support clean URLs.
Apache: Add .htaccess with rewrite rules.
Nginx: Already configured in examples.
THYPRESS is open source (MPL-2.0) and welcomes contributions.
- 🐛 Report bugs: GitHub Issues
- 💡 Suggest features: GitHub Discussions
- 📖 Improve docs: Edit README, create guides
- 🎨 Create themes: Share your designs
- 🌍 Showcase your site: Submit to gallery
Setup:
git clone https://github.com/thypress/binder.git
cd binder
bun install
bun src/cli.js servePull Request Process:
- Create feature branch
- Make changes
- Test thoroughly
- Commit with clear message
- Open PR on GitHub
For personal sites: Yes. Stable and performant.
For company sites: Use with caution. The project is new, single maintainer.
For enterprise: Wait for v1.0+ (6-12 months).
Existing tools are either too complex, too slow, too opinionated, or build-only.
THYPRESS is: simple, fast, flexible, and dual-mode (build OR serve).
Three optimizations:
- Pre-rendering: All pages rendered at startup
- Pre-compression: Brotli + gzip pre-compressed
- Bun runtime: Fast JavaScript execution
Speed: Bun is considerably faster for I/O.
Simplicity: bun build --compile creates a single binary.
Modern: Built-in TypeScript, JSX.
Node support: Not yet. Bun-only for now.
No. THYPRESS uses Handlebars (server-side HTML).
Workaround: Add client-side JavaScript in templates.
Better choice: Use Gatsby/Next.js for React apps.
No. Everything is built-in.
Future: Simple hook system for custom processing (see Roadmap).
Yes. Export WordPress content to XML, convert to Markdown (use tools like wordpress-export-to-markdown), copy to THYPRESS content/ folder.
Yes. See Raspberry Pi deployment guide.
- Docker official image
- Health check endpoint (
/__thypress/health) - Metrics endpoint (
/__thypress/metrics) - Security headers (CSP, X-Frame-Options, etc.)
- CI/CD pipeline
- Migration scripts (WordPress, Medium, Jekyll)
- More themes
- Simple hook system (beforeBuild, afterBuild)
- Custom markdown-it plugins via config
- Theme management CLI (
thypress theme install) - Rate limiting (optional)
- Multi-site support
- Scheduled rebuilds
- Incremental builds
- Browser sync for hot reload
Mozilla Public License 2.0 (MPL-2.0)
What this means:
- ✅ Use commercially
- ✅ Modify and distribute
- ✅ Private use
⚠️ Disclose source for modified files
Full license: LICENSE or mozilla.org/MPL/2.0
Built with:
- Bun - Fast JavaScript runtime
- markdown-it - Markdown parser
- Handlebars - Templating
- Sharp - Image processing
- highlight.js - Syntax highlighting
- MiniSearch - Client-side search
Inspired by Hugo, Jekyll, and Eleventy.
- Issues: github.com/thypress/binder/issues
- Discussions: github.com/thypress/binder/discussions
- Email: hi@thypress.org
- X: @thypressdotorg
Built with ❤️ & 💧 by teo
THYPRESS™ © 2025
Made with THYPRESS? Show us your project →