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

MossJump to section titled Moss

Moss Logo

A whimsical static site generator for building blogs with Markdown and Vue

InstallationFeaturesGetting StartedCLI ReferenceConfiguration


InstallationJump to section titled Installation

System RequirementsJump to section titled System Requirements

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"
}
Note
If you use 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:

Example:

moss serve
moss serve ./my-blog

moss build [directory]Jump to section titled moss build [directory]

Builds your site for production.

Options:

Example:

moss build
moss build ./my-blog

moss helpJump to section titled moss help

Shows help information and usage examples.

Example:

moss help
moss --help
moss -h

moss versionJump 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)DescriptionDefault
titledisplayNameSite titlename from package.json
descriptiondescriptionSite description for SEO-
authorauthorAuthor name-
baseUrlhomepageBase URL for the site-
iconiconPath to site icon/favicon-
outDir-Output directory for built site.moss/dist
cleanUrls-Generate clean URLstrue
giscusgiscusGiscus configuration for comments-
counterscalecounterscaleCounterscale 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:

Clean URLsJump to section titled Clean URLs

Moss automatically generates clean URLs for your pages:

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]
---
FieldDescriptionDefault
titlePage titleFirst H1 heading
descriptionPage descriptionAuto-generated from content
layoutLayout template (article, default or homepage)default
typeContent type (article, page, or homepage)article
tagsArray 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

  1. Enable GitHub Discussions on your repository (Settings → Features → Discussions)

  2. Install the Giscus app on your repository: github.com/apps/giscus

  3. Configure Giscus by visiting giscus.app and following the setup wizard

  4. Add configuration to your package.json or moss.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

FieldDescriptionRequired
repoGitHub repository in owner/name formatYes
repoIdRepository ID (get from giscus.app)Yes
categoryDiscussion category nameYes
categoryIdDiscussion 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

FieldDescriptionRequired
siteIdYour site identifierYes
scriptURL to the Counterscale trackerYes

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:

Custom LayoutsJump to section titled Custom Layouts

Moss supports different layout types via frontmatter:

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:

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