⚠️ Warning: This project is work in progress and is currently private. It has not been published yet.
MossJump to section titled Moss
A whimsical static site generator for building blogs with Markdown and Vue
Installation • Features • Getting Started • CLI Reference • Configuration
InstallationJump to section titled Installation
System RequirementsJump to section titled System Requirements
- Node.js 22.17.0 or later
- npm, yarn, or pnpm
Install MossJump to section titled Install Moss
Install Moss globally to use the CLI:
pnpm add -g @znck/moss
Or use it locally in your project:
pnpm add -D @znck/moss
FeaturesJump to section titled Features
✨ 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 StartedJump to section titled Getting Started
1. Create a new projectJump to section titled 1. Create a new project
mkdir my-blog
cd my-blog
pnpm init -y
2. Install MossJump to section titled 2. Install Moss
pnpm add -D @znck/moss
3. Create configuration file (optional)Jump to section titled 3. 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 postJump to section titled 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 optimization
5. Start the development serverJump to section titled 5. Start the development server
pnpx moss serve
Your site will be available at http://localhost:5173
6. Build for productionJump to section titled 6. Build for production
pnpx moss build
The built site will be in the .moss/dist
directory.
DeploymentJump to section titled 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 8000
CLI ReferenceJump to section titled CLI Reference
moss serve [directory]
Jump to section titled 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-blog
moss build [directory]
Jump to section titled moss 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-blog
moss help
Jump to section titled moss help
Shows help information and usage examples.
Example:
moss help
moss --help
moss -h
moss version
Jump to section titled moss version
Shows the current version of Moss.
Example:
moss version
moss --version
moss -v
ConfigurationJump to section titled Configuration
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 OptionsJump to section titled 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 FieldsJump to section titled 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 DirectoriesJump to section titled 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 URLsJump to section titled Clean URLs
Moss automatically generates clean URLs for your pages:
about.md
→/about/
posts/my-post.md
→/posts/my-post/
index.md
→/
(homepage)
Frontmatter OptionsJump to section titled 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 GiscusJump to section titled 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 GiscusJump to section titled 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.json
ormoss.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 OptionsJump to section titled 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 PagesJump to section titled 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 CounterscaleJump to section titled 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 CounterscaleJump to section titled 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 OptionsJump to section titled 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 StructureJump to section titled 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 UsageJump to section titled Advanced Usage
Vue ComponentsJump to section titled 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 LayoutsJump to section titled 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 SitesJump to section titled 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.
ContributingJump to section titled Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
LicenseJump to section titled License
MIT License - see LICENSE file for details.
Made with ❤️ by @znck