{"id":21631136,"url":"https://github.com/gavinmcfarland/stancy","last_synced_at":"2025-09-20T07:48:41.080Z","repository":{"id":38252695,"uuid":"253850774","full_name":"gavinmcfarland/stancy","owner":"gavinmcfarland","description":"A simple API for delivering content from static files and folders.","archived":false,"fork":false,"pushed_at":"2024-07-23T12:23:48.000Z","size":19763,"stargazers_count":8,"open_issues_count":51,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-06T22:49:05.921Z","etag":null,"topics":["api","file-based-cms","flat-file","headless-cms","rest-like","static"],"latest_commit_sha":null,"homepage":"https://stancy.vercel.app/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gavinmcfarland.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2020-04-07T16:27:44.000Z","updated_at":"2024-07-23T12:23:51.000Z","dependencies_parsed_at":"2024-11-25T02:13:34.019Z","dependency_job_id":"e991444a-edf1-49f8-a1e4-8774ad75a082","html_url":"https://github.com/gavinmcfarland/stancy","commit_stats":null,"previous_names":["limitlessloop/stancy"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/gavinmcfarland/stancy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmcfarland%2Fstancy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmcfarland%2Fstancy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmcfarland%2Fstancy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmcfarland%2Fstancy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gavinmcfarland","download_url":"https://codeload.github.com/gavinmcfarland/stancy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gavinmcfarland%2Fstancy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275055088,"owners_count":25397576,"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","status":"online","status_checked_at":"2025-09-14T02:00:10.474Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["api","file-based-cms","flat-file","headless-cms","rest-like","static"],"created_at":"2024-11-25T02:13:19.430Z","updated_at":"2025-09-20T07:48:41.059Z","avatar_url":"https://github.com/gavinmcfarland.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Stancy\n\n![npm](https://img.shields.io/npm/v/stancy)\n\nStancy uses static files and folders to generate a database of collections and items. The database can be queried as a plain object, outputted as a json file, or served using an express server for a RESTlike API. This is useful for building static sites which use frameworks like React, Vue, Svelte or Marko. Stancy is unbiased about how you use it and can be customised to suit different use-cases.\n\n- [Example](#example)\n- [Installation](#installation)\n- [Features](#features)\n- [Docs](#docs)\n- [Development](#development)\n\n\n## Example\n\nIn this example, we'll look at how we can create a database from static files and folders which can be accessed using an API for a website.\n\nStart by creating a folder with some content, below is an example. Each top level file or folder creates a root endpoint.\n\n```bash\ncontent/\n  site.json\n  pages/\n    home.md\n    about.md\n    services.md\n```\n\nHere we've created a file `site.json` which stores key information about our site, some `pages`, and a `blog`.\n\nNow start the server.\n\n```js\nstancy('content/').server(3000, '/api/')\n```\n\nWe can access the content using the following requests:\n\n- [localhost:3000/api/site](http://localhost:3000/api/site)\n- [localhost:3000/api/pages](http://localhost:3000/api/pages)\n- [localhost:3000/api/pages/about](http://localhost:3000/api/pages/about)\n\nCheck out the [examples](/examples).\n\n## Installation\n\nAdd the npm package to your project.\n\n```bash\nnpm install stancy\n```\n\n## Features\n\n- ### Server and client\n    \n    Easily serve content from static folders and files, and fetch content.\n\n---\n\n- ### Collections and Items\n\n  Collections are created by plural sounding folders. Items are created using files and non-plural sounding folders.\n\n---\n\n- ### Preprocess data\n\n  Easily sort collections, format dates, and parse content on the client.\n\n---\n\n- ### Index File\n\n  This is useful if you prefer to organise using folders or if you want to create an index page for a group of related content.\n\n  ```bash\n  # Creates a collection of items\n  posts/\n    item-one.md\n    item-two.md\n    item-three.md\n\n  # Creates an item\n  item/\n    index.md\n  ```\n\n---\n\n- ### Hidden\n\n  Prepend an underscore to hide a file or folder. In the case of hiding a folder, this will also hide all it's contents.\n\n  ```\n  _file-is-hidden.md\n  _folder-is-hidden/\n  ```\n\n---\n\n- ### File Types \u003cmark\u003e(Planned)\u003c/mark\u003e\n\n  The following file types are supported.\n\n  - Archives\n  - Audio\n  - Code\n  - Documents\n  - Images\n  - Videos\n\n---\n\n- ### Meta Data \u003cmark\u003e(Planned)\u003c/mark\u003e\n\n  You can add meta data to images by creating a data file with a matching name.\n\n  ```\n  my-first-post/\n    playing-frisbee.jpg\n    playing-frisbee.yml\n  ```\n\n  This will create the following image meta data\n\n  ```jsonc\n  {\n    // ...\n    \"images\": [\n      {\n        \"src\": \"/static/playing-frisbee.jpg\",\n        \"alt\": \"Me playing frisbee\"\n      }\n    ]\n  }\n  ```\n\n---\n\n- ### Built in Fields\n\n    If you create a database you can filter and show data using a query language of your choice using the following field names.\n\n    #### Private\n\n    - `_name` Name of the resource\n    - `_collection` Collection the resource belongs to\n    - `_index` The index of the resource in the collection or dataset\n    - `_type` The type of resource. Named after the folder or file.\n    - `_source` The path to the folder containing the file.\n\n\n    #### Public\n\n    - `url` The url to the resource.\n    \n\n## Docs\n\n- ### Starting a server\n\n    `stancy(source).server([port, path])`\n\n    #### Arguments\n\n    - __`source`__ { String } source of the content directory to be servered\n    - __`port`__ { Number }\n    - __`path`__ { String } subpath where API will be accessible from \n\n    #### Example\n\n    ```js\n    stancy('content/').server(3000, '/api/')\n    ```\n\n---\n\n- ### Starting a client\n\n    `stancy([source]).client(url)`\n\n    #### Arguments\n\n    - __`url`__ { String } url of the production server\n\n\n    #### Example\n\n    ```js\n    stancy('content/').client('http://domain.com/api/')\n    ```\n---\n\n- ### Preprocessing data\n\n    `client.preprocess([type,] callback)`\n\n    Useful for sorting collections, formatting dates, or parsing markdown.\n\n    #### Arguments\n\n    - __`type`__ { String } can be one of the following:\n        - __`collection`__ returns every collection as an array of objects.\n        - __`item`__ returns every item as an object with key value pairs.\n        - __`content`__ returns value of every item with a property of _content_.\n    - __`callback`__ { function } gives access to one of the types of `data` above.\n\n    #### Examples\n\n    An example of sorting collections by date\n\n    ```js\n    client.preprocess('collection', (data) =\u003e {\n        return data.sort((a, b) =\u003e {\n            if (a.date \u003e b.date) {\n                return 1;\n            } else if (a.date \u003c b.date) {\n                return -1\n            } else {\n                return 0\n            }\n        })\n    })\n    ```\n\n    An example of formatting machine readable dates\n\n    ```js\n    client.preprocess('item', (data) =\u003e {\n        return data.date = new Date(data.date)\n    })\n    ```\n\n    An example of parsing markdown\n\n    ```js\n    client.preprocess('content', (data) =\u003e {\n        return marked(data)\n    })\n    ```\n---\n\n- ### Getting data\n\n    ```js\n    client.get('users/jerry').then(res =\u003e {\n        console.log(res)\n    }).catch(err =\u003e { \n        console.log(err)\n    })\n    ```\n\n    Example response\n\n    ```json\n    {\n        \"url\": \"users/jerry\",\n        \"name\": \"Jerry\",\n        \"age\": \"24\",\n        \"role\": \"admin\",\n        \"content\": \"\u003ch1\u003eJerry\u003c/h1\u003e\"\n    }\n    ```\n---\n\n- ### Creating a database\n\n    `stancy(source).database()`\n\n    #### Example\n\n    ```js\n    var database = stancy('content/').database()\n    ```\n---\n\n- ### Configure using config file \u003cmark\u003e(Planned)\u003c/mark\u003e\n\n    __stancy.config.js__\n\n    ```js\n    {\n        source: 'content/',\n        client: {\n            production: 'https://stancy.now.sh/api/',\n            token: 'T89ALS90',\n            preprocess: ({content}) =\u003e {\n                content = marked(content)\n            }\n        }\n    }\n    ```\n\n    #### Specify custom config file\n\n    ```js\n    stancy().config('src/stancy.config.js')\n    ```\n\n## Development\n\nTo install the dependencies\n\n```\nnpm install\n```\n\nTo run the demo server\n\n```\nnpm run demo\n```\n\nTo run tests\n\n```\nnpm run test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgavinmcfarland%2Fstancy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgavinmcfarland%2Fstancy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgavinmcfarland%2Fstancy/lists"}