{"id":25344590,"url":"https://github.com/jbukuts/git-cms","last_synced_at":"2026-04-16T10:03:36.931Z","repository":{"id":229093149,"uuid":"775747426","full_name":"jbukuts/git-cms","owner":"jbukuts","description":"Source raw Markdown content from GitHub repository in a predictable type-safe manner like a CMS","archived":false,"fork":false,"pushed_at":"2024-03-25T14:34:04.000Z","size":587,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-14T11:43:49.854Z","etag":null,"topics":["cms","git","headless-cms","markdown","node"],"latest_commit_sha":null,"homepage":"https://jbukuts.github.io/git-cms/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jbukuts.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-22T01:00:57.000Z","updated_at":"2024-03-22T21:42:30.000Z","dependencies_parsed_at":"2024-03-22T02:25:17.375Z","dependency_job_id":"17a198db-5cba-40f8-8f8b-5426765718bf","html_url":"https://github.com/jbukuts/git-cms","commit_stats":null,"previous_names":["jbukuts/git-cms"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbukuts%2Fgit-cms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbukuts%2Fgit-cms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbukuts%2Fgit-cms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbukuts%2Fgit-cms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jbukuts","download_url":"https://codeload.github.com/jbukuts/git-cms/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247867362,"owners_count":21009240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","git","headless-cms","markdown","node"],"created_at":"2025-02-14T11:37:47.968Z","updated_at":"2026-04-16T10:03:31.887Z","avatar_url":"https://github.com/jbukuts.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-cms\n\n\u003cp\u003e\n    \u003ca href=\"https://www.npmjs.com/package/git-as-a-cms\"\u003e\n        \u003cimg src=\"https://img.shields.io/npm/v/git-as-a-cms\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/jbukuts/git-cms/blob/main/LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/npm/l/git-as-a-cms\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/git-as-a-cms\"\u003e\n        \u003cimg src=\"https://img.shields.io/npm/unpacked-size/git-as-a-cms\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nUse a GitHub repository as a headless CMS to source Markdown content.\n\nBuilt on top of the GitHub REST API using `octokit`.\n \n## What is this?\n\nThis project makes it easier to source `md`/`mdx` from a GitHub repository so that it can be transformed and used with your page generation.\n\nThis allows you to separate your site code from your static content while still using GitHub all around.\n\nEssentially it's just a fancy wrapper for various GitHub API calls to get you your content in a predictable and type-safe manner.\n\n## When to use this?\n\nDo you want to use GitHub as a CMS to store and source your content remotely from one place without the need to use or host another tool?\n\nThen this may be of some use to you.\n\nThis tool is not designed to replace something like Sanity. It's more for people who like to have flexibility in how they edit their content and like to use GitHub normally.\n\n## Installation\n\n```bash\nnpm install git-as-a-cms\n```\n\n## API\n\nBelow are examples of using the exposed APIs.\n\n### `new GitCMS()`\n\nCreating an instance is easy:\n\n```js\nconst gitCMS = new GitCMS({\n  // your API key\n  apiKey: 'your-key-here'\n  // username of repo owner\n  owner: 'octo',\n  // name of the repo\n  repo: 'whatever',\n  // where to start sourcing content in the repo\n  srcPath: '/path/to/souce/from'\n})\n```\n\nIf you want better type prediction you can also instantiate the class with a generic representing the shape of your frontmatter data. \n\nThis can even be combined with the `schema` object you pass into the constructor via `from-schema-to-ts` like so:\n\n```ts\nimport GitCMS from 'git-cms'\nimport { FromSchema } from 'json-schema-to-ts'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    desc: {\n      type: 'string'\n    }\n  },\n  required: ['desc']\n} as const\n\ntype FrontMatter = FromSchema\u003ctypeof schema\u003e\n\nconst gitCMS = new GitCMS\u003cFrontMatter\u003e({\n  apiKey: 'your-key-here'\n  owner: 'octo',\n  repo: 'kit',\n  srcPath: '/path/to/souce/from'\n})\n```\n\nNow if any of the frontmatter data sourced from content doesn't conform to your schema's shape an error will be thrown when sourcing content. \n\nAlso, when using the frontmatter data down the line you'll have access to information about its shape.\n\n### `listItems()`\n\nThis function will return a list of all the content sourced from the repository. \n\nBy default, the returned list will also include the raw markup content. If you'd like to disable this you can set `includeContent` to `false` and instead fetch content later via the `getItemBySha` or `getItemByPath` methods of the class with the returned values of each item.\n\nA use case like that would look like so:\n\n```ts\nconst contentList = await gitCMS.listItems({\n  // content extensions. currently only supports md/mdx\n  extensions: ['.md'],\n  // optional path to source if different from constructor. overides `srcPath`\n  path: '/test_docs'\n  // whether to recurse through file structure\n  recursive: true,\n  // dont include content in each item\n  includeContent: false\n})\n\n// get plaintext content for all items\nfor await (const item of contentList) {\n  const { sha, frontmatter, full_path } = item \n\n  // will be typed by input schema generic\n  console.log(frontmatter)\n\n  // how to get content when not returned in list\n  const rawContent: string = await gitCMS.getItemBySha({ sha })\n\n  // or with other method\n  const rawContentAgain: string = await gitCCMS.getItemByPath({ path: full_path })\n  console.log(rawContent)\n}\n```\n\n## Limitations\n\nThis tool is designed to be **READ ONLY** to your content with the default use of GitHub being the intended use case for updating content.\n\nDepending on the amount of content you want to source you may run into [rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28) set by the GitHub API.\n\nAlso, the content returned to you will be raw Markdown in its plaintext form. This keeps the response agnostic to your use case. For transforming content for rendering that will depend on your tech stack. \n\nHere's a list of common tools by framework:\n\n- Next.js: `next-mdx-remote`\n- SvelteKit: `mdsvex`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbukuts%2Fgit-cms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjbukuts%2Fgit-cms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbukuts%2Fgit-cms/lists"}