Skip to content

sphido/sphido

Repository files navigation

A rocket 🚀 fast, 💭 lightweight and flexible static site 🤖 generator.

NPM Downloads NPM Version NPM License Last Commit GitHub Workflow Status

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

Installation

The fastest way to start is the scaffolder — it generates a small working blog:

npm create sphido my-blog

Or add the core package to an existing project:

pnpm add @sphido/core

or

npm i @sphido/core

The Quick Start below also uses marked and @sindresorhus/slugify — install them alongside:

pnpm add marked @sindresorhus/slugify

Monorepo development

Use pnpm; the intended version is pinned in the root packageManager field.

pnpm install
pnpm build
pnpm test

Quick Start

#!/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.

Run script

node index.js

Packages

  • @sphido/core - core functions getPages(), allPages(), readFile() and writeFile()

Page extenders

Website components

Helpers

TypeScript

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`;
});

Examples

License

MIT

About

A rocket 🚀 fast, light-weight and flexible static site generator.

Topics

Resources

License

Stars

38 stars

Watchers

3 watching

Forks

Contributors