⚠️ Warning: This project is work in progress and is currently private. It has not been published yet.
Moss

A whimsical static site generator for building blogs with Markdown and Vue
Installation • Features • Getting Started • CLI Reference • Configuration
Installation
System Requirements
- Node.js 22.17.0 or later
- npm, yarn, or pnpm
Install Moss
Install Moss globally to use the CLI:
pnpm add -g @znck/mossOr use it locally in your project:
pnpm add -D @znck/mossFeatures
✨ Markdown-First: Write your content in Markdown with frontmatter support
⚡ Fast Development: Hot-reload development server with Vite
🔗 Clean URLs: Automatic clean URL generation for better SEO
📱 SEO Optimized: Canonical URLs, meta tags, and structured data
🎭 RSS/Atom Feeds: Automatic feed generation for your blog
📦 Zero Config: Works out of the box with sensible defaults
🔧 Customizable: Flexible configuration and theming options
🚀 TypeScript Support: Built with TypeScript for better developer experience
📝 Syntax Highlighting: Code blocks with syntax highlighting via Shiki
🧮 Math Support: LaTeX math rendering with KaTeX
🏷️ Tag Support: Organize content with tags and categories
💬 Comments: Built-in Giscus integration for GitHub Discussions-powered comments
📊 Analytics: Privacy-focused analytics with Counterscale support
Getting Started
1. Create a new project
mkdir my-blog
cd my-blog
pnpm init -y2. Install Moss
pnpm add -D @znck/moss3. Create configuration file (optional)
Moss works out of the box with zero configuration, but you can customize your site by creating a moss.json file or adding configuration to your package.json:
Option A: Using moss.json
{
"title": "My Blog",
"description": "This is my first blog using Moss",
"author": "Your Name"
}Option B: Using package.json
{
"name": "my-blog",
"displayName": "My Blog",
"description": "This is my first blog using Moss",
"author": "Your Name"
}moss.json, package.json fields will be ignored.4. Create your first post
Create an index.md file:
---
title: Welcome to My Blog
description: This is my first blog post using Moss
---
# Welcome to My Blog
This is my first blog post built with **Moss**!
Moss makes it easy to create beautiful, fast static sites with Markdown and Vue.
## Features I love
- Easy Markdown writing
- Vue component support
- Fast development server
- SEO optimization5. Start the development server
pnpx moss serveYour site will be available at http://localhost:5173
6. Build for production
pnpx moss buildThe built site will be in the .moss/dist directory.
Deployment
After building, you can deploy the contents of .moss/dist to any static hosting service:
# Build the site
moss build
# Deploy to various platforms
# Netlify
netlify deploy --prod --dir .moss/dist
# Vercel
vercel --prod .moss/dist
# GitHub Pages (copy to docs folder)
cp -r .moss/dist/* docs/
# Or serve locally for testing
cd .moss/dist && python -m http.server 8000CLI Reference
moss serve [directory]
Starts a development server for your site.
Options:
directory- The root directory of your site (defaults to current directory)
Example:
moss serve
moss serve ./my-blogmoss build [directory]
Builds your site for production.
Options:
directory- The root directory of your site (defaults to current directory)
Example:
moss build
moss build ./my-blogmoss help
Shows help information and usage examples.
Example:
moss help
moss --help
moss -hmoss version
Shows the current version of Moss.
Example:
moss version
moss --version
moss -vConfiguration
Moss works with zero configuration out of the box, but you can customize your site using either a dedicated moss.json file or by adding configuration to your existing package.json. Configuration in moss.json takes priority over package.json.
Configuration Options
Using moss.json (recommended for dedicated configuration):
{
"title": "My Awesome Blog",
"description": "A blog about web development and technology",
"author": "Your Name",
"baseUrl": "https://yourdomain.com",
"icon": "path/to/favicon.ico"
}Using package.json (convenient for simple projects):
{
"name": "my-blog",
"displayName": "My Awesome Blog",
"description": "A blog about web development and technology",
"author": "Your Name",
"homepage": "https://yourdomain.com",
"icon": "path/to/favicon.ico"
}Supported Configuration Fields
| Field (moss.json) | Field (package.json) | Description | Default |
|---|---|---|---|
title | displayName | Site title | name from package.json |
description | description | Site description for SEO | - |
author | author | Author name | - |
baseUrl | homepage | Base URL for the site | - |
icon | icon | Path to site icon/favicon | - |
outDir | - | Output directory for built site | .moss/dist |
cleanUrls | - | Generate clean URLs | true |
giscus | giscus | Giscus configuration for comments | - |
counterscale | counterscale | Counterscale analytics configuration | - |
Ignored Files and Directories
By default, Moss ignores the following directories when scanning for Markdown files:
node_modules/- Node.js dependenciespublic/- Static assets (typically served directly)DRAFT/- Draft content not ready for publication- Hidden directories (starting with
.)
Clean URLs
Moss automatically generates clean URLs for your pages:
about.md→/about/posts/my-post.md→/posts/my-post/index.md→/(homepage)
Frontmatter Options
Each Markdown file can include frontmatter with the following options:
---
title: Page Title
description: Page description for SEO
layout: default # or 'homepage'
type: article # or 'page' or 'homepage'
tags: [web, javascript, tutorial]
---| Field | Description | Default |
|---|---|---|
title | Page title | First H1 heading |
description | Page description | Auto-generated from content |
layout | Layout template (article, default or homepage) | default |
type | Content type (article, page, or homepage) | article |
tags | Array of tags | [] |
Comments with Giscus
Moss includes built-in support for Giscus, a comments system powered by GitHub Discussions. Comments are automatically added to all article pages when configured.
Setting up Giscus
Enable GitHub Discussions on your repository (Settings → Features → Discussions)
Install the Giscus app on your repository: github.com/apps/giscus
Configure Giscus by visiting giscus.app and following the setup wizard
Add configuration to your
package.jsonormoss.json:
Using package.json:
{
"giscus": {
"repo": "owner/repository",
"repoId": "R_kgDOxxxxxxx",
"category": "Announcements",
"categoryId": "DIC_kwDOxxxxxxx"
}
}Using moss.json:
{
"giscus": {
"repo": "owner/repository",
"repoId": "R_kgDOxxxxxxx",
"category": "Announcements",
"categoryId": "DIC_kwDOxxxxxxx"
}
}Giscus Configuration Options
| Field | Description | Required |
|---|---|---|
repo | GitHub repository in owner/name format | Yes |
repoId | Repository ID (get from giscus.app) | Yes |
category | Discussion category name | Yes |
categoryId | Discussion category ID (get from giscus.app) | Yes |
Additional Giscus options are supported. Visit giscus.app for the complete configuration guide.
Disabling reactions on Specific Pages
You can disable reactions on individual pages by adding reactions: false to the frontmatter:
---
title: My Private Post
reactions: false
---Analytics with Counterscale
Moss supports Counterscale, a privacy-focused, cookieless analytics platform. The analytics script is automatically included in production builds when configured.
Setting up Counterscale
Using package.json:
{
"counterscale": {
"siteId": "example.com",
"script": "https://analytics.example.com/tracker.js"
}
}Using moss.json:
{
"counterscale": {
"siteId": "example.com",
"script": "https://analytics.example.com/tracker.js"
}
}Counterscale Configuration Options
| Field | Description | Required |
|---|---|---|
siteId | Your site identifier | Yes |
script | URL to the Counterscale tracker | Yes |
Note: The analytics script is only loaded in production builds (moss build), not during development (moss serve).
Directory Structure
A typical Moss project structure:
my-blog/
├── package.json # Basic project info and optional config
├── moss.json # Optional dedicated config file
├── index.md # Homepage
├── about.md # About page
├── posts/ # Blog posts
│ ├── first-post.md
│ └── second-post.md
└── .moss/ # Generated files (git-ignored)
└── dist/ # Built site
Advanced Usage
Vue Components
You can use Vue components directly in your Markdown:
# My Post
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
Click count: {{ count }}
<button @click="count++">Increment</button>Moss uses Vue 3 with the Composition API, giving you access to all modern Vue features including:
- Composition API with
<script setup> - Reactivity (ref, reactive, computed, watch)
- Lifecycle hooks (onMounted, onUnmounted, etc.)
- Custom components and imports
Custom Layouts
Moss supports different layout types via frontmatter:
homepage- Minimal layout for your main landing pagedefault- Standard layout with header and navigation (used for both articles and pages)
The layout is determined by the frontmatter layout field, but the type field helps with content categorization:
---
title: My Homepage
layout: homepage # Uses minimal homepage layout
type: homepage # Content type for categorization
------
title: My Blog Post
layout: default # Uses standard layout (default)
type: article # Content type for categorization
---Example Sites
Looking for inspiration? Check out these websites built with Moss:
- znck.dev - Personal blog with Giscus comments and Counterscale analytics
- moss.znck.dev - Documentation for Moss
You can also explore the znck.dev source code in this repository under apps/znck.dev/ to see a real-world example of Moss configuration including Giscus and Counterscale setup.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details.
Made with ❤️ by @znck