Disclaimer: All code in this system was generated by AI.
Demo:
A modern, static blog system built with React, Vite, and TypeScript. Powered by a Rust-based build engine for native performance.
- Tech Stack: React 19, Vite, TypeScript, Rust (build engine)
- Content: Markdown-based posts (Hexo-compatible frontmatter)
- Features:
- Instant Search
- Archives (Year/Month)
- Tags & Categories
- i18n Support (English, Chinese, Japanese)
- Photo Albums with EXIF metadata
- SEO (sitemap, RSS, Open Graph, JSON-LD)
- Styling: Clean, responsive design with Tailwind CSS
- Performance: Static site generation with Rust-powered build pipeline
The fastest way to create a new blog:
npm create s-blog@latestTip: You can also use
bunx create-s-blog my-blogorpnpm create s-blog my-blog.
The CLI will guide you through project setup. After initialization:
cd my-blog
npm install
npm run devnpm run buildThis single command handles the full pipeline:
- Copies the pre-built App Shell
- Generates posts manifest and copies Markdown files
- Processes album photos (thumbnails + EXIF extraction)
- Generates SEO pages, sitemap.xml, rss.xml, robots.txt
The output is a fully static site in dist/. Deploy it to any static hosting.
npm update @s-blog/core @s-blog/engineYou only maintain your content files (posts/, config.json, album.config.json, albums/, public/). Framework updates are delivered through packages.
S-Blog is published as three npm packages:
| Package | Purpose |
|---|---|
@s-blog/core |
Pre-built App Shell, UI components, routing, styles, JSON schemas |
@s-blog/engine |
Rust-powered build engine — Markdown parsing, image processing, SEO generation, dev server |
create-s-blog |
CLI scaffolding tool — npm create s-blog |
Your project only contains content and configuration:
my-blog/
├── posts/ # Markdown posts
├── albums/ # Photo albums (optional)
├── public/ # Static assets (logo, favicon)
├── config.json # Site configuration
├── album.config.json # Album configuration
└── package.json
{
"title": "My Blog",
"description": "A personal blog",
"logo": "/logo.png",
"favicon": "/favicon.ico",
"siteUrl": "https://example.com",
"author": "Your Name",
"language": "en",
"timezone": "Asia/Tokyo",
"links": {
"enabled": true,
"items": {
"Friend Blog": "https://example.com"
}
},
"socialLinks": {
"enabled": true,
"items": [
{ "platform": "rss" },
{ "platform": "github", "url": "https://github.com/username/repo" },
{ "platform": "x", "url": "https://x.com/username" },
{ "platform": "custom", "url": "https://example.com", "icon": "/icons/my-icon.png", "label": "My Site" }
]
}
}| Field | Required | Description |
|---|---|---|
title |
Yes | Website title |
description |
Yes | Website description |
logo |
Yes | Logo image path |
favicon |
Yes | Favicon path |
siteUrl |
No | Production URL. Required for SEO features (sitemap, RSS, Open Graph) |
author |
No | Author name for SEO metadata |
language |
No | Default language code (en, zh-CN, ja). Affects i18n fallback behavior |
timezone |
No | IANA timezone (e.g., Asia/Shanghai). Ensures correct post dates when building on CI |
basePath |
No | Sub-directory deployment path (e.g., /blog). Defaults to / |
links |
No | Friend links widget (see below) |
socialLinks |
No | Social icon links widget (see below) |
Displays a list of text links in the right sidebar (desktop) or footer (mobile).
| Field | Required | Description |
|---|---|---|
links.enabled |
Yes | Toggle the links widget on/off |
links.items |
Yes | Key-value pairs: { "Display Name": "URL" } |
Displays a row of icon links. Built-in platforms: github, rss, x, twitter, weibo, zhihu, bilibili, email, facebook, instagram, tiktok.
| Field | Required | Description |
|---|---|---|
socialLinks.enabled |
Yes | Toggle the social links widget on/off |
socialLinks.items |
Yes | Array of social link items |
items[].platform |
Yes | Platform name (built-in) or "custom" for custom icons |
items[].url |
Depends | URL to link to. Optional for rss (auto-derived from siteUrl), required for others |
items[].icon |
No | Custom icon image path. Used when platform is "custom" or unrecognized |
items[].label |
No | Tooltip text. Defaults to platform name |
Note: If
platformis"rss"andurlis omitted, the URL is automatically set to{siteUrl}/rss.xml. IfsiteUrlis not configured, the RSS item will not be rendered.
{
"enabled": true,
"albums": [
{ "dir": "travel-2024", "name": "2024 Travel", "cover": "cover.jpg" },
{ "dir": "日常", "cover": "best.jpg" }
]
}| Field | Required | Description |
|---|---|---|
enabled |
Yes | Toggle the entire album module on/off |
albums[].dir |
Yes | Directory name under albums/. Supports letters, numbers, hyphens, underscores, CJK characters |
albums[].name |
No | Display name. Defaults to dir |
albums[].cover |
No | Cover photo filename. Falls back to the first photo |
Add Markdown files to posts/:
---
title: My Post Title
date: 2024-01-01 12:00:00
tags: [Tech, React]
categories: [Programming]
preview: A short description for post previews.
---To publish a post in multiple languages, use filename suffixes:
posts/
├── About.md # Default (matches site language or English)
├── About.zh-CN.md # Chinese version
└── About.ja.md # Japanese version
The system automatically detects available languages and shows a fallback notice when a localized version is unavailable.
Place photos in albums/{dirname}/. Supported formats: .jpg, .jpeg, .png, .webp
The build process automatically:
- Generates WebP thumbnails (max 1080px)
- Extracts EXIF metadata (camera, lens, aperture, shutter speed, ISO)
- Produces JSON index files
Thumbnails are generated incrementally — unchanged photos are skipped.
When siteUrl is configured, the build automatically generates:
- SEO HTML pages (
dist/post/*/index.html) — Open Graph, Twitter Card, JSON-LD - sitemap.xml — XML sitemap
- rss.xml — RSS 2.0 feed
- robots.txt — Crawler instructions
This project strictly prohibits manual coding. All code must be generated by AI.
- Gemini 3 Pro
- Gemini 3.1 Pro
- Claude Sonnet 4.5
- Claude Opus 4.5
- Claude Opus 4.6