{"id":23143713,"url":"https://github.com/xieyuheng/fidb-zero","last_synced_at":"2026-04-28T20:02:38.359Z","repository":{"id":258026006,"uuid":"523575104","full_name":"xieyuheng/fidb-zero","owner":"xieyuheng","description":"What if we use file system as database?","archived":false,"fork":false,"pushed_at":"2025-03-23T11:12:43.000Z","size":1626,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-29T05:37:37.709Z","etag":null,"topics":["database","db","file","filesystem","fs","nosql","relational-database","schemaless"],"latest_commit_sha":null,"homepage":"https://fidb.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xieyuheng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-08-11T03:36:43.000Z","updated_at":"2025-03-23T11:12:47.000Z","dependencies_parsed_at":"2024-11-16T23:02:59.048Z","dependency_job_id":"6b835857-0edf-4099-8720-e3b8192f8630","html_url":"https://github.com/xieyuheng/fidb-zero","commit_stats":{"total_commits":1315,"total_committers":1,"mean_commits":1315.0,"dds":0.0,"last_synced_commit":"2e13cf13d76ca0b2b37497290d7d6721aa76ab75"},"previous_names":["fidb-official/fidb-zero","xieyuheng/fidb"],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/xieyuheng/fidb-zero","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xieyuheng%2Ffidb-zero","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xieyuheng%2Ffidb-zero/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xieyuheng%2Ffidb-zero/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xieyuheng%2Ffidb-zero/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xieyuheng","download_url":"https://codeload.github.com/xieyuheng/fidb-zero/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xieyuheng%2Ffidb-zero/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32396781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T19:38:08.556Z","status":"ssl_error","status_checked_at":"2026-04-28T19:37:55.688Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["database","db","file","filesystem","fs","nosql","relational-database","schemaless"],"created_at":"2024-12-17T15:14:04.073Z","updated_at":"2026-04-28T20:02:38.337Z","avatar_url":"https://github.com/xieyuheng.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FiDB\n\nThis is a Node.js implementation of **FiDB**\n-- a suite of protocols to use file system as database.\n\nIncluding a command-line tool to initialize and maintain database.\n\n```\nCommands:\n  help [name]             Display help for a command\n  init:database [path]    Initialize a directory to be a database\n  serve:database [path]   Serve a database\n  serve:subdomain [path]  Serve many databases using subdomain-based routing\n```\n\nAnd a HTTP server to generate REST API from a database.\n\n```\nPOST   {data-path}?kind=data\nGET    {data-path}?kind=data\nPUT    {data-path}?kind=data\nPATCH  {data-path}?kind=data\nDELETE {data-path}?kind=data\n\nGET    {data-directory}?kind=data-find\n\nPOST   {file}?kind=file\nGET    {file}?kind=file\nPUT    {flie}?kind=file\nDELETE {flie}?kind=file\n\nGET    {flie}?kind=file-metadata\n\nPOST   {flie}?kind=file-rename\n\nPOST   {directory}?kind=directory\nGET    {directory}?kind=directory\nDELETE {directory}?kind=directory\n```\n\n## Ethos\n\nThe ethos of the FiDB project is the following \"what if ...?\"s.\n\n\u003e What if we use file system as database?\n\n\u003e What if we generate HTTP API from the database, \u003cbr\u003e\n\u003e instead of writing trivial CRUD code over and over again?\n\n\u003e What if we write web apps in a way that a user can switch backend, \u003cbr\u003e\n\u003e even using their local backend?\n\n## Install\n\n### Requirements\n\nNode.js version must\nbe \u003e= [20.8.0](https://nodejs.org/en/blog/release/v20.8.0).\n\n- For the `recursive` option to `readdir` and `opendir`.\n\n### Command line tool\n\nInstall it by the following command:\n\n```sh\nnpm install -g fidb\n```\n\nThe command-line program is called `fidb`.\n\n## Docs\n\n- [Init a database](#init-a-database)\n- [Serve one database](#serve-one-database)\n- [Serve many databases](#serve-many-databases)\n- [Register a user](#register-a-user)\n- [Login a user](#login-a-user)\n- [Config logger](#config-logger)\n- [Get free certificate](#get-free-certificate)\n- [Use systemd to start service](#use-systemd-to-start-service)\n\n### Init a database\n\nA database is just a directory of subdirectories and JSON data files,\nwith a `database.json` config file,\nand with some more data files serve as\ndetailed system configurations.\n\nUse the `fidb init:database` command to create a database:\n\n```sh\nfidb init:database hello-world\n```\n\nExample console output of `fidb init:database`:\n\n```\n17:07:19.297 [init] -- {\"directory\":\"/databases/hello-world\"}\n17:07:19.301 [initDatabaseConfigFile] -- {\"file\":\"/databases/hello-world/database.json\"}\n```\n\nLet's see what files are created:\n\n```\ndatabase.json\n.groups/guest/index.json\n.groups/owner/index.json\n.groups/user/index.json\n.guest-token-issuer/index.json\n.tokens/guest/index.json\n```\n\n## Serve one database\n\nUse the `fidb serve:database` command to serve a database:\n\n```sh\nfidb serve:database hello-world\n```\n\nThe default port of the server is `5108`, which looks like FiDB isn't it?\n\n## Serve many databases\n\nUse the `fidb serve:subdomain` command\nto serve many databases in one directory,\nusing subdomain-based routing.\n\nFor example, I have a VPS machine,\nwhere I put all my databases\nin the `/databases` directory.\n\n```\n/databases/x-wiki\n/databases/x-news\n...\n```\n\nI bought a domain for my server -- say `example.com`,\nand configured my DNS to resolve `example.com`\nand `*.example.com` to my server.\n\nI also created certificate files for my domain using `certbot`.\n\n- About how to use `certbot`, please see\n  the [\"Get free certificate\"](#get-free-certificate) section.\n\nI can use `fidb serve:subdomain` command to serve all of\nthe databases in `/databases` directory.\n\n```sh\nfidb serve:subdomain /databases/database.json\n```\n\nWhere `/databases/database.json` is:\n\n```json\n{\n  \"server\": {\n    \"hostname\": \"example.com\",\n    \"port\": 5108,\n    \"tls\": {\n      \"cert\": \"/etc/letsencrypt/live/example.com/fullchain.pem\",\n      \"key\": \"/etc/letsencrypt/live/example.com/privkey.pem\"\n    }\n  }\n}\n```\n\n- When using `fidb serve:subdomain`,\n  the `server.hostname` option is required.\n\n- And each database in `/databases` might have\n  it's own `database.json` config file.\n\nThen I can access all my databases via subdomain of `example.com`.\n\n```\nhttps://x-wiki.example.com:5108\nhttps://x-news.example.com:5108\n...\n```\n\nIf no subdomain is given in a request,\n`www/` will be used as the default subdomain directory\n(while no redirect will be done).\n\nThus the following websites have the same contents:\n\n```\nhttps://example.com:5108\nhttps://www.example.com:5108\n```\n\n## Register a user\n\nUse `POST {data-file}?kind=password-register` HTTP request to register a new user:\n\n```sh\ncurl -X POST \"http://127.0.0.1:5108/users/alice?kind=password-register\" --data-binary @-\u003c\u003c END\n\n{\n  \"password\": \"wonderland\",\n  \"data\": {\n    \"name\": \"Alice\"\n  }\n}\n\nEND\n```\n\nExample response:\n\n```json\n{\n  \"name\": \"Alice\",\n  \"@path\": \"users/alice\",\n  \"@revision\": \"b0b913da866105ad66299baf6aa4d783\",\n  \"@createdAt\": 1696152632809,\n  \"@updatedAt\": 1696152632809\n}\n```\n\nNew data files for the user will be created:\n\n```\nusers/alice/index.json\nusers/alice/.password/index.json\nusers/alice/.token-issuer/index.json\n```\n\n## Login a user\n\nUse `POST {data-file}?kind=password-login` HTTP request to login an initialized user:\n\n```sh\ncurl -X POST \"http://127.0.0.1:5108/users/alice?kind=password-login\" --data-binary @-\u003c\u003c END\n\n{\n  \"password\": \"wonderland\"\n}\n\nEND\n```\n\nExample response:\n\n```json\n\n{ \"token\":\"07cb46bde600f9ab97a22ecee8bc2389\" }\n```\n\nNew data file for the token will be created:\n\n```\n.tokens/07cb46bde600f9ab97a22ecee8bc2389/index.json\n```\n\nWhich can be used in the `Authorization` header for future requests.\n\n```\nAuthorization: token 34dbf6a79e7968ffc3cda1b51c3fada9\n```\n\n### Config logger\n\nWe can config logger in `/databases/database.json`:\n\n```json\n{\n  ...,\n  \"logger\": {\n    \"name\": \"pretty-line\",\n    \"disableRequestLogging\": true\n  }\n}\n```\n\nThe type of logger options are:\n\n```ts\nexport type LoggerOptions = {\n  name: \"json\" | \"silent\" | \"pretty\" | \"pretty-line\"\n  disableRequestLogging?: boolean\n}\n```\n\nThe default logger options are:\n\n```json\n{\n  \"name\": \"pretty-line\",\n  \"disableRequestLogging\": false\n}\n```\n\n### Get free certificate\n\nYou can use `certbot` to get free certificate for your domains.\n\n- [Certbot website](https://certbot.eff.org/instructions)\n- [Certbot on archlinux wiki](https://wiki.archlinux.org/title/certbot)\n\nAfter install `certbot`,\nI prefer creating certificate via DNS TXT record,\nusing the following command:\n\n```sh\nsudo certbot certonly --manual --preferred-challenges dns\n```\n\nThen you can follow the prompt of `certbot`\nto create the certificate files,\nduring which you will need to add TXT record\nto the DNS record of your domain\nto accomplish the challenge given by `certbot`.\n\n### Use systemd to start service\n\nInstall service:\n\n```\nsudo cp \u003cname\u003e.service /etc/systemd/system/\n```\n\nUsing service:\n\n```\nsudo systemctl start \u003cname\u003e.service\nsudo systemctl enable \u003cname\u003e.service\nsudo systemctl status \u003cname\u003e.service\n```\n\nTo view log:\n\n```\njournalctl -f -u \u003cname\u003e.service\n```\n\nReload systemd config files:\n\n```\nsudo systemctl daemon-reload\n```\n\n## Development\n\n```sh\nnpm install           # Install dependencies\nnpm run build         # Compile `src/` to `lib/`\nnpm run build:watch   # Watch the compilation\nnpm run format        # Format the code\nnpm run test          # Run test\nnpm run test:watch    # Watch the testing\n```\n\n## License\n\n[GPLv3](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxieyuheng%2Ffidb-zero","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxieyuheng%2Ffidb-zero","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxieyuheng%2Ffidb-zero/lists"}