I know, another static site generator! This one is different - it's totally minimalistic.
Basically, it's just two functions. The first, the getPages() function, allows you to retrieve a list of pages, and the allPages() function allows
you to iterate through them.
You get a static site generator that is:
- 🚀 rocket fast
- 💭 lightweight
- 🤘 zero-dependency core
- ⚡️ flexible
The fastest way to start is the scaffolder — it generates a small working blog:
npm create sphido my-blogOr add the core package to an existing project:
pnpm add @sphido/coreor
npm i @sphido/coreThe Quick Start below also uses marked and @sindresorhus/slugify — install them alongside:
pnpm add marked @sindresorhus/slugifyUse pnpm; the intended version is pinned in the root packageManager field.
pnpm install
pnpm build
pnpm test#!/usr/bin/env node
import {dirname, join, relative} from 'node:path';
import {allPages, getPages, readFile, writeFile} from '@sphido/core';
import slugify from '@sindresorhus/slugify';
import {marked} from 'marked';
const pages = await getPages({path: 'content'}, // ... extenders
(page) => {
page.slug = slugify(page.name) + '.html';
page.dir = dirname(page.path);
});
for (const page of allPages(pages)) {
page.output = join('public', relative('content', page.dir), page.slug);
page.content = marked(await readFile(page.path));
await writeFile(page.output, `<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
<title>${page.name} | Sphido Example</title>
</head>
<body class="prose mx-auto my-6">${page.content}</body>
<!-- Generated by Sphido from ${page.path} -->
</html>`);
}Sphido requires Node.js 22 or newer. To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
node index.js@sphido/core- core functionsgetPages(),allPages(),readFile()andwriteFile()
@sphido/frontmatter- frontmatter extender forpage@sphido/hashtags- process hashtags inpage.content
@sphido/sitemap- generatesitemap.xmlfile@sphido/feed- generate RSS 2.0feed.xmlfile
@sphido/collections- sorting, pagination, tag pages and prev/next navigation@sphido/dev- dev server with watch mode and live reloadcreate-sphido- project scaffolder fornpm create sphido
Extender packages export the types they contribute to pages, so you can compose a fully typed page:
import {getPages, allPages, type Page} from '@sphido/core';
import {frontmatter, type WithFrontmatter} from '@sphido/frontmatter';
import {hashtags, type WithHashtags} from '@sphido/hashtags';
type BlogPage = Page & WithFrontmatter & WithHashtags & {slug: string};
const pages = await getPages<BlogPage>({path: 'content'}, frontmatter, hashtags, (page) => {
page.slug = `${page.name}.html`;
});