{"id":13911095,"url":"https://github.com/TimMikeladze/markdown-to-api","last_synced_at":"2025-07-18T10:32:22.069Z","repository":{"id":65561174,"uuid":"524250832","full_name":"TimMikeladze/markdown-to-api","owner":"TimMikeladze","description":"📑 Generates a minisearch powered GraphQL API from a directory of markdown files. Additional metadata like tags or descriptions can be added to the files in the form of YAML front matter, which will then be indexed and available to search by.","archived":false,"fork":false,"pushed_at":"2023-03-16T21:33:10.000Z","size":258,"stargazers_count":15,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-09T07:05:01.729Z","etag":null,"topics":["graphql","markdown","markdown-api","markdown-graphql","nextjs","static-site-generator"],"latest_commit_sha":null,"homepage":"https://markdown-to-api-example.vercel.app","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/TimMikeladze.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","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},"funding":{"ko_fi":"linesofcodedev","custom":["https://www.paypal.me/TimMikeladze"]}},"created_at":"2022-08-12T23:39:33.000Z","updated_at":"2025-02-06T06:33:21.000Z","dependencies_parsed_at":"2024-10-23T12:11:40.784Z","dependency_job_id":null,"html_url":"https://github.com/TimMikeladze/markdown-to-api","commit_stats":{"total_commits":26,"total_committers":2,"mean_commits":13.0,"dds":"0.038461538461538436","last_synced_commit":"0e7f66f93b471d54f6578b739ff7b2c7ac84ca6d"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/TimMikeladze/markdown-to-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimMikeladze%2Fmarkdown-to-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimMikeladze%2Fmarkdown-to-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimMikeladze%2Fmarkdown-to-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimMikeladze%2Fmarkdown-to-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TimMikeladze","download_url":"https://codeload.github.com/TimMikeladze/markdown-to-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimMikeladze%2Fmarkdown-to-api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265742419,"owners_count":23820837,"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":["graphql","markdown","markdown-api","markdown-graphql","nextjs","static-site-generator"],"created_at":"2024-08-07T00:01:57.430Z","updated_at":"2025-07-18T10:32:21.757Z","avatar_url":"https://github.com/TimMikeladze.png","language":"TypeScript","funding_links":["https://ko-fi.com/linesofcodedev","https://www.paypal.me/TimMikeladze"],"categories":["TypeScript"],"sub_categories":[],"readme":"# Markdown To API\n\nThis package generates a GraphQL API from a directory of Markdown files. Additional metadata like tags, descriptions, or custom fields can be added to the Markdown files in the form of YAML front matter, a simple schema at the top of each file. These fields will be indexed and available to query and filter by in the GraphQL API.\n\n## Installation\n\n```shell\nnpm install markdown-to-api --save\n# or\nyarn add markdown-to-api\n# or\npnpm add markdown-to-api\n```\n\n## Example\n\nThis [example repository](https://github.com/TimMikeladze/markdown-to-api-example) shows how `markdown-to-api` is used in conjunction with NextJS's Static Generation and Server-side Rendering features to create a searchable site with all the content residing in markdown files. The deployed example can be seen at [https://markdown-to-api-example.vercel.app](https://markdown-to-api-example.vercel.app).\n\n## Usage\n\n### Initialize\n\n```typescript\nimport { MarkdownAPI } from 'markdown-to-api'\n\nconst mdapi = new MarkdownAPI({\n  directory: `./markdown`,\n  // In development mode a minisearch index file will be generated.\n  writeIndex: process.env.NODE_ENV !== 'production',\n  // In production mode, if a minisearch index file is found, it will be used.\n  useIndex: process.env.NODE_ENV === 'production',\n  // This field is optional, but if provided minisearch will be instantiated with these options. See [minisearch](https://github.com/lucaong/minisearch) to learn more. This is helpful to adjust how your files are indexed and searched.\n  miniSearchOptions: {},\n});\n```\n\n### Content and Configuration\n\n#### Markdown files\n\nEach markdown file can contain an optional YAML front matter schema.\n\nBelow is markdown file showcasing such a schema.\n\n```markdown\n---\ntitle: About Tigers\ndescription: The tiger (Panthera tigris) is the largest living cat species and a member of the genus Panthera.\ntags:\n- cat\n- tiger\ngenus: Panthera\n---\n\n# About Tigers\n\nThe tiger (Panthera tigris) is the largest living cat species and a member of the genus Panthera.\n\nIt is most recognisable for its dark vertical stripes on orange fur with a white underside. An apex predator, it primarily preys on ungulates, such as deer and wild boar.\n\n```\n\nThe following keys are special in the context of `markdown-to-api`. They will be indexed and available to query and filter by in the generated API.\n\n- `id`: A unique identifier for the markdown file. (Optional, if not provided it will be generated based off of the file path and title.)\n- `title`: The title of the markdown file. (Optional, will be generated from the filename if not provided.)\n- `description`: The description of the markdown file. (Optional)\n- `tags`: An array of tag ids for the markdown file. (Optional). If a `config.yml` file exists than these tag ids must correspond to the tags defined in `config.yml`\n- `createdAt`: An ISO 8601 formatted date string. (Optional)\n\n#### Config file\n\nIn the root of the directory where the markdown files are located, a `config.yml` file can be used to define tags and other metadata such as making certain fields required.\n\nIn the example below we define a list of tags pertaining to felines, make the `tags` field required and define a new field `genus` marked as required. Now each markdown file we define must include `tags` field and a `genus` field.\n\n```yaml\ntags:\n  cat:\n    description: Fits into any box.\n  puma:\n    name: cougar / puma\n    description: Puma is a large cat, also known as a mountain lion.\n  tiger:\n    description: Tiger is a very large cat.\n  lion:\n    description: Lions have manes.\nfields:\n  tags:\n    required: true\n  genus:\n    required: true\n```\n\n### CLI\n\n`markdown-to-api` generates an `index.json` file used for searching through the markdown files. During development this file will be generated automatically, however when running via CI/CD or as part of your build process it is useful to generate this file via a script.\n\n```shell\nnode node_modules/markdown-to-api/dist/cli.mjs -d markdown\n```\n\nThis command can be added to the `scripts` section of your `package.json` file. See the [example repository](https://github.com/TimMikeladze/markdown-to-api-example) to see how this works in action.\n\n\n### Searching\n\n```typescript\n// Search all files for the term `cat`.\nmdapi.getIndex().search('tiger');\n\n// Search only tags field for the term `tiger`.\nmdapi.getIndex().search('tiger', { fields: ['tags'] });\n```\n\nAdditional options can be passed to the search method. This is an options object which is passed to [minisearch](https://github.com/lucaong/minisearch).\n\n### GraphQL API\n\n### GraphQL Module\n\nA GraphQL Module is included in this package which encapsulates the schema and resolvers provided by `markdown-to-api`. The example below shows how you can instantiate a new module which can then be consumed by your GraphQL server of choice.\n\n```typescript\nimport { createApplication } from 'graphql-modules';\nimport createMarkdownAPIModule } from 'markdown-to-api';\n\nconst markdownAPIModule = createMarkdownAPIModule({\n  directory: `./markdown`,\n  // In development mode a minisearch index file will be generated.\n  writeIndex: process.env.NODE_ENV !== 'production',\n  // In production mode, if a minisearch index file is found, it will be used.\n  useIndex: process.env.NODE_ENV === 'production',\n});\n\nconst app = createApplication({\n  modules: [markdownAPIModule],\n});\n```\n\n#### Example queries\n\n```graphql\nquery SearchMarkdownFiles {\n  searchMarkdownFiles(text: \"tigers\") {\n    count\n    results {\n      id\n      title\n      description\n      createdAt\n      tags {\n        id\n        name\n        description\n      }\n      markdownFile {\n        content\n      }\n    }\n  }\n}\n```\n\n```graphql\nquery SearchTags {\n  searchMarkdownFiles(text: \"lion\", options: { fields: [\"tags\"] }) {\n    count\n    results {\n      id\n      title\n      description\n      createdAt\n      tags {\n        id\n        name\n        description\n      }\n      markdownFile {\n         content\n      }\n    }\n  }\n}\n```\n\n```graphql\nquery AllFilesAndTags {\n  countMarkdownFiles\n  markdownFiles {\n    id\n    title\n    content\n    tags {\n      id\n      name\n      description\n    }\n  }\n  markdownFileTags {\n    id\n    name\n    description\n  }\n}\n\n```\n\n#### Generate schema\n\n```graphql\ntype Query {\n  countMarkdownFiles: Int\n  markdownFile(id: ID!): MarkdownFile!\n  markdownFiles(direction: MarkdownFilesSortDirection, limit: Int, offset: Int): [MarkdownFile!]!\n  searchMarkdownFiles(text: String!, options: MarkdownFileSearchOptions, limit: Int, offset: Int): MarkdownFileSearchResults!\n  autoSuggestMarkdownFileSearch(text: String!, options: MarkdownFileSearchOptions): MarkdownFileAutoSuggestResults!\n  markdownFileTags: [MarkdownFileTag!]!\n}\n\ntype MarkdownFile {\n  content: String!\n  strippedContent: String!\n  id: ID!\n  path: String!\n  slug: String!\n  tags: [MarkdownFileTag!]!\n  title: String!\n  description: String\n  createdAt: String!\n}\n\ntype MarkdownFileSearchResults {\n  count: Int!\n  results: [MarkdownFileSearchResult!]!\n}\n\ntype MarkdownFileSearchResult {\n  id: ID!\n  description: String\n  score: Float!\n  terms: [String!]\n  title: String!\n  slug: String!\n  path: String!\n  tags: [MarkdownFileTag!]!\n  createdAt: String!\n  markdownFile: MarkdownFile!\n}\n\ntype MarkdownFileTag {\n  id: ID!\n  name: String!\n  description: String\n}\n\ninput MarkdownFileSearchOptions {\n  fields: [String!]\n  weights: MarkdownFileSearchOptionsWeights\n  prefix: Boolean\n  fuzzy: Boolean\n  maxFuzzy: Int\n  combineWith: MarkdownFileSearchOptionsCombineWith\n}\n\ntype MarkdownFileAutoSuggestResults {\n  count: Int!\n  results: [MarkdownFileAutoSuggestResult!]!\n}\n\ntype MarkdownFileAutoSuggestResult {\n  suggestion: String!\n  terms: [String!]!\n  score: Float!\n}\n\nenum MarkdownFileSearchOptionsCombineWith {\n  AND\n  OR\n}\n\ninput MarkdownFileSearchOptionsWeights {\n  fuzzy: Float!\n  exact: Float!\n}\n\nenum MarkdownFilesSortDirection {\n  asc\n  desc\n}\n\nenum MarkdownFilesSortBy {\n  title\n  createdAt\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTimMikeladze%2Fmarkdown-to-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTimMikeladze%2Fmarkdown-to-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTimMikeladze%2Fmarkdown-to-api/lists"}