@asahi-fj/structcms
v0.1.6
Published
GitHub as a CMS — fetch, transform, render content via GitHub API
Downloads
433
Maintainers
Keywords
Readme
structcms
Use GitHub as a headless CMS. Fetch and transform content stored in a GitHub repository via the GitHub API.
Why structcms?
structcms treats a GitHub repository as your content store — no extra infrastructure, no vendor lock-in.
| Feature | structcms | Outstatic | Decap CMS | Contentlayer | |---|---|---|---|---| | Zero added infrastructure | ✅ No DB, no server | ✅ | ⚠️ Needs Git Gateway / Netlify | ✅ | | Separate content & app repos | ✅ Any repo, any owner | ❌ Same repo only | ⚠️ Manual config | ❌ Local files only | | Private repository support | ✅ Token-based access | ❌ Public repos only | ⚠️ Limited | ✅ | | Setup requirement | GitHub Token only | GitHub OAuth App | Netlify / OAuth | Local file system |
How it works
Store content under a contents/ directory in any GitHub repository. Each piece of content lives in its own slug-named folder with a Markdown file and a JSON metadata file.
your-content-repo/
└── contents/
├── hello-world/
│ ├── content.md
│ └── meta.json
└── my-second-post/
├── content.md
└── meta.jsonInstallation
npm install @asahi-fj/structcmsQuick start
import StructCms from "@asahi-fj/structcms";
const cms = StructCms({
token: process.env.GITHUB_TOKEN!,
owner: "your-org",
repo: "your-content-repo",
});
const posts = await cms.getAll();
// [{ slug: "hello-world", content: "# Hello\n...", meta: { title: "Hello World", ... } }]See USAGE.md for full examples.
Content format
meta.json
{
"title": "Post title",
"description": "A short description",
"publishedAt": "2026-04-11",
"draft": false,
"tags": ["typescript", "cms"]
}content.md — standard Markdown.
API
| Method | Description |
|---|---|
| cms.getAll() | Fetch all content entries |
| cms.getById(id) | Fetch a single entry by slug (coming soon) |
Requirements
- Node.js 18+
- GitHub Personal Access Token with read access to the content repository
License
ISC
