Quick start for developers

This guide takes you from zero to a live site. Estimated time: under 20 minutes.

Prerequisites

  • Node.js 22 or later (node --version to check)
  • npm 10+ or pnpm 9+ (pnpm is recommended)
  • A GitHub account
  • A Cloudflare account (free tier works)

Step 1: Create the project

npm create @karaoke-cms@latest my-site
cd my-site

The scaffolder creates an Astro project with a sample vault at karaoke-website-vault/, a karaoke.config.ts, and GitHub Actions config.

Install dependencies:

pnpm install

Step 2: Open the vault in Obsidian (optional)

The vault folder (karaoke-website-vault/ by default) is a plain folder of Markdown files. Open it as a vault in Obsidian if you want to write with Obsidian’s editor. You can also use any text editor.

Step 3: Configure karaoke.config.ts

The scaffolded config is already functional. A minimal version looks like this:

import { defineConfig } from '@karaoke-cms/astro';
import { loadEnv } from '@karaoke-cms/astro/env';
import { blog } from '@karaoke-cms/module-blog';
import { docs } from '@karaoke-cms/module-docs';
import { seo } from '@karaoke-cms/module-seo';
import { tags } from '@karaoke-cms/module-tags';
import { search } from '@karaoke-cms/module-search';
import { themeDefault } from '@karaoke-cms/theme-default';

const env = loadEnv(new URL('.', import.meta.url));

export default defineConfig({
  vault: env.KARAOKE_VAULT,
  title: 'My Site',
  description: 'What this site is about.',
  theme: themeDefault(),
  modules: [
    blog({ mount: '/blog' }),
    docs({ mount: '/docs' }),
    seo(),
    tags(),
    search(),
  ],
});

The vault path comes from .env.default (committed) or .env (local override, gitignored). The default is KARAOKE_VAULT=./karaoke-website-vault/.

To add comments via Giscus, first enable Discussions on your GitHub repo, get your values from giscus.app, then add:

import { comments } from '@karaoke-cms/module-comments';

// inside modules[]:
blog({ mount: '/blog', comments: true }),
comments({
  repo: 'owner/repo',
  repoId: 'R_...',
  category: 'General',
  categoryId: 'DIC_...',
}),

Step 4: Write a blog post

Create karaoke-website-vault/blog/hello-world.md:

---
title: "Hello, world"
publish: true
date: 2024-01-01
description: "My first post."
tags: [intro]
---

This is my first post. It will appear on the site because `publish: true`.

Any file without publish: true is invisible in production, regardless of where it lives in the vault.

Step 5: Run the dev server

pnpm dev

Open http://localhost:4321. Your post appears at /blog/hello-world.

Changes to vault files are picked up on save. If you change KARAOKE_VAULT in .env.default, clear the content cache first:

rm -rf apps/website/.astro

Step 6: Push to GitHub

Initialize git if the scaffolder didn’t:

git init
git add .
git commit -m "Initial commit"

Create a repo on GitHub, then push:

git remote add origin https://github.com/your-username/my-site.git
git push -u origin main

Step 7: Deploy to Cloudflare Pages

  1. Go to dash.cloudflare.com and open Workers & Pages.
  2. Click Create, then Pages, then Connect to Git.
  3. Select your repository.
  4. Set the build configuration:
    • Framework preset: None
    • Build command: pnpm build
    • Build output directory: dist
  5. Add these environment variables under Settings > Environment variables:
    • KARAOKE_VAULT = ./karaoke-website-vault/
  6. Click Save and Deploy.

The first deploy takes about two minutes. After that, every push to main triggers a new build automatically.

Alternatives to Cloudflare Pages: karaoke-cms outputs a standard Astro static build. Any static host works (Netlify, Vercel, GitHub Pages). The .github/workflows/deploy.yml is wired for Cloudflare but easy to adapt.

What you should see

  • Home page at the root URL
  • Blog post at /blog/hello-world
  • Docs at /docs (if you have docs with publish: true)
  • Tag index at /tags
  • Search at /search (requires at least one build to index content)

Private files (no publish: true) never appear, confirmed by the assert-privacy check that runs as part of the build.