{"id":26670761,"url":"https://github.com/crbroughton/sibyl","last_synced_at":"2026-04-11T13:11:23.254Z","repository":{"id":226772125,"uuid":"769620896","full_name":"CRBroughton/Sibyl","owner":"CRBroughton","description":"A lightweight, type-safe query builder for sql.js, libSQL \u0026 Bun","archived":false,"fork":false,"pushed_at":"2024-05-11T08:15:16.000Z","size":609,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-20T00:57:28.376Z","etag":null,"topics":["bun","database","db","embedded","sql","sqlite","typescript","wasm"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@crbroughton/sibyl","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/CRBroughton.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-09T15:38:32.000Z","updated_at":"2024-05-11T08:15:19.000Z","dependencies_parsed_at":"2024-04-27T19:31:47.192Z","dependency_job_id":null,"html_url":"https://github.com/CRBroughton/Sibyl","commit_stats":null,"previous_names":["crbroughton/sibyl"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/CRBroughton/Sibyl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CRBroughton%2FSibyl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CRBroughton%2FSibyl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CRBroughton%2FSibyl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CRBroughton%2FSibyl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CRBroughton","download_url":"https://codeload.github.com/CRBroughton/Sibyl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CRBroughton%2FSibyl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31681574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T13:07:20.380Z","status":"ssl_error","status_checked_at":"2026-04-11T13:06:47.903Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["bun","database","db","embedded","sql","sqlite","typescript","wasm"],"created_at":"2025-03-25T22:46:19.493Z","updated_at":"2026-04-11T13:11:23.239Z","avatar_url":"https://github.com/CRBroughton.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sibyl\n\nSibyl is a lightweight SQLite query builder for \u003ca href=\"https://github.com/sql-js/sql.js\"\u003eSQL.js\u003c/a\u003e, \u003ca href=\"https://bun.sh/docs/api/sqlite\"\u003eBun's sqlite3 driver\u003c/a\u003e, and \u003ca href=\"https://github.com/tursodatabase/libsql\"\u003elibSQL\u003c/a\u003e, providing a Prisma-like query builder. Sibyl is in early development,\nso expect breaking changes and rapid development.\n\n## Getting Started\n\n### Installation\n\nDependant on your chosen SQLite driver, you'll want to follow one\nof the following installation methods:\n\n#### SQL.js Installation\n\nIf you choose to use Sibyl with `sql.js`, `sql.js` will provide the lower-level API to interact with your\nembedded SQLite database. You'll also need to install the `.wasm` file that `sql.js`\nprovides; Please see their documentation at https://sql.js.org.\n\nThe SQL.js implementation has been tested against SQL.js version 1.10.2.\n\nWith the `.wasm` file now available, you can install Sibyl with the following command:\n\n```bash\nbun install sql.js @types/sql.js @crbroughton/sibyl\n```\n\n#### Bun Installation\n\nIf you are using Sibyl with Bun, you should already have access to the driver, and can refer to the \u003ca href=\"https://bun.sh/docs/api/sqlite\"\u003e\nBun documentation\u003c/a\u003e. The Bun implemenation of Sibyl can be installed\nwith the following command:\n\n```bash\nbun install @crbroughton/sibyl_bun\n```\nSibyl will then accept the native Bun SQLite `Database`, again, see the \u003ca href=\"https://bun.sh/docs/api/sqlite\"\u003e\nBun documentation\u003c/a\u003e.\n\nThe Bun implementation has been tested against Bun version 1.1.3.\n\n#### libSQL Installation\n\nThe libSQL implemenation of Sibyl can be installed\nwith the following command:\n\n```bash\nbun install @crbroughton/sibyl_libsql libsql\n```\nSibyl will then accept libSQL `Database`, then see the \u003ca href=\"https://github.com/tursodatabase/libsql-js?tab=readme-ov-file#getting-started\"\u003e\nlibSQL Getting Started Guide\u003c/a\u003e.\n\nThe libSQL implementation has been tested against libSQL version 0.3.11.\n\n#### Getting Started\n\nTo start off with Sibyl, you'll first have to ensure Sibyl is able to be run inside\nof a top-level async/await file, alongside your `sql.js` database connection. As\nreferenced from the `sql.js` documentation, you can provide Sibyl a database instance\nlike so:\n\n```typescript\ninterface tableRowType {\n  id: number\n  name: string\n  sex: string\n  job: string\n  hasReadTheReadme: boolean\n}\n\ninterface secondRowType {\n  id: number\n}\n\ninterface Tables {\n  firstTable: tableRowType\n  secondTable: secondRowType\n}\n\nconst SQL = await sql({ // sql.js implementation\n  locateFile: () =\u003e {\n    return '/sql-wasm.wasm'\n  }\n})\nconst db = new SQL.Database()\n\nconst { createTable, Insert, Select, All, Create } = await Sibyl\u003cTables\u003e(db)\n```\n\nWith top-level async/await enabled, you can then use Sibyl. Sibyl provides the following\nfunctions:\n\n- `createTable` - Allows you to create a table\n- `Create` - Creates and returns a new entry into your selected table\n- `Insert` - Allows you to provide an array of insertable entries into your selected table\n- `Select` - Returns a type-safe array of entries from the selected table\n- `LimitedSelect` - Returns a type-safe, limited array of entries from\nthe selected table\n- `All` - Returns all entries from the selected table\n- `Update` Updates and returns a single entry from the selected table\n- `Delete` - Deletes an entry from a selected table\n\n### Creating the table\n\nTo create a new table, use the `createTable` command:\n\n```typescript\ncreateTable('firstTable', { // inferred table name and entry\n  id: {\n    autoincrement: true,\n    type: 'INTEGER', // only allows for known data types ('int', 'char', 'blob')\n    primary: true,\n    unique: true,\n  },\n  job: {\n    type: 'varchar',\n    size: 100, // specify the size of the varchar\n    nullable: true\n  },\n  name: {\n    type: 'char',\n    size: 4,\n  },\n  sex: {\n    type: 'char',\n    size: 3,\n  },\n  hasReadTheReadme: {\n    type: 'bool',\n  },\n})\n```\n\n`createTable` takes two arguments, the first is the name of the table you wish to select, This\nis based off the generic interface you first supplied to Sibyl.\nThe second argument will create the specified columns for your database. Sibyl will handle the order and creation of each column you have specified, and only allow known data types.\n\n### Inserting a single entry into the DB\n\nTo create a new entry, you can use the `Create` function:\n\n```typescript\nconst result = Create('firstTable', { // returns the resulting entry\n    id: faker.number.int(),\n    name: 'Craig',\n    sex: 'male',\n    job: 'Software Engineer',\n    hasReadTheReadme: true,\n})\n```\n\n### Inserting mutiple entries into the DB\n\nTo insert new entries into the database, you can use the `Insert` function:\n\n```typescript\nlet insertions: SibylResponse\u003ctableRowType\u003e[] = []\nfor (let index = 0; index \u003c 1000; index++) {\n  insertions.push({\n    id: faker.number.int(),\n    name: faker.person.firstName(),\n    sex: faker.person.sex(),\n    job: faker.person.jobTitle(),\n    hasReadTheReadme: true,\n  })\n}\n// execute the provided instruction - Data will now be in the DB\nconst test = Insert('firstTable', insertions)\n```\n\n### Selecting entries from the DB\n\nWhen selecting entries from the database, you can utilise the `Select` function\nto retrieve an array of type-safe entries, based from the generic interface\nyou have supplied to Sibyl main function (see above `tableRowType`).\n\n```typescript\nselection.value = Select('firstTable', {\n   where: {\n    id: 1,\n    name: \"Craig\", // can combine multiple where clauses\n   },\n   limit: 20, // limit the response from Sibyl\n   offset: 10, // offset the response, useful for pagination\n})\n```\n\n### Selecting limited entries from the DB\n\nWhen selecting entries from the database but you want to be selective about the responses values, you can utilise the `LimitedSelect` function\nto retrieve an array of type-safe entries, based from the generic interface\nyou have supplied to Sibyl main function (see above `tableRowType`).\n\nThe core difference here is that the `where` clause now also controls\nwhat values you get back.\n\n```typescript\nselection.value = LimitedSelect('firstTable', {\n   where: {\n    id: 1,\n    name: \"Craig\", // can combine multiple where clauses\n   },\n   limit: 20, // limit the response from Sibyl\n   offset: 10, // offset the response, useful for pagination\n})\n```\n\n#### OR Selection\n\nWhen selecting entries from the database, the `Select` function, by\ndefault, uses an AND statement to build you query. You can however,\ninclude an optional OR array to select entries:\n\n```typescript\nconst response = Select('firstTable', { // Returns all entries where name is Craig OR Bob\n  where: {\n    OR: [\n      {\n        name: 'Craig'\n      },\n      {\n        name: 'Bob'\n      }\n    ]\n  }\n})\n```\n\nYou can also combine multiple OR statements as part of a single object,\nif the keys do no clash:\n\n```typescript\nconst response = Select('firstTable', { // Returns all entries where name is Craig OR Bob OR hasReadTheReadme is false\n  where: {\n    OR: [\n      {\n        name: 'Craig',\n        hasReadTheReadme: 0, // boolean values need to be selected\n                             // based on their database values\n                             // and will be returned as such\n      },\n      {\n        name: 'Bob'\n      }\n    ]\n  }\n})\n```\nWhen using the optional OR array to build a query, you can still use\nthe optional `offset` and `limit` keys.\n\n### Updating an entry in the DB\n\nTo update a single entry in the database, you can use the `Update` function:\n\n```typescript\nconst updatedEntry = Update('firstTable', { // infers the table and response type\n   where: { // Can combine multiple where clauses\n    id: 1,\n    name: 'Craig',\n   },\n   updates: {\n    name: 'Bob', // Can update multiple values at once\n    job: 'Engineer',\n   }\n})\n```\n### Sorting\n\nSibyl offers some basic sorting options, whenever you're returning\nentries from the database:\n\n```typescript\nconst actual = All('firstTable', {\n  sort: {\n    name: 'ASC', // This can be 'ASC' or 'DESC'\n  },\n})\n```\n\n### Primary type\n\nSibyl offers a custom type, called the 'primary' type. When using\nthis type, Sibyl will automatically set the entry to a primary key,\nnot nullable and unique. Sibyl will also ensure that the underlying\ntype changes, so your editor gives feedback about no longer requiring\nyou to manually set these keys. Currently the primary type is only\navailable as an integer type.\n\n### Sibyl Responses\n\nSibyl also offers a custom type the `SibylResponse` type; This type can be helpful\nwhen wanting to convert data types to TypeScript types; At the moment the custom type\nonly support boolean conversions from `boolean` to `0 | 1`. It's recommended to use\nthis type as a wrapper, if you're ever using boolean values.\n\n### Working With Reactivity\n\nWhen working with any front-end framework, you'll want to combine\nSibyl with your frameworks reactivity engine. I've provided some\nexamples in the playground, in this case using Vue, but in general\nyou should follow the following rules:\n\n- Sibyl is not responsive by default; You should aim for Sibyls\nresponses to end up in a reactive object (see ref for Vue).\n- When working with your reactive state, it's good practice to ensure\nthat the states type is the same of that of the response type from\nSibyl\n- Sibyl provides the `SibylResponse` type; You can use this type\nas a 'wrapper' type like so:\n\n```typescript\nconst results = ref\u003cSibylResponse\u003cOrder\u003e[]\u003e([])\n```\nThis ensures that when you work with the `results` array, it conforms\nto the shape and type Sibyl will return.\n\n## Development\n\nTo install dependencies:\n\n```bash\nbun install\n```\n\nYou can then try Sibyl in the playground, first install the dependencies:\n\n```bash\ncd playground \u0026\u0026 bun install\n```\n\nand then run the playground:\n```bash\nbun run dev\n```\n\nThis project was created using `bun init` in bun v1.0.29. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrbroughton%2Fsibyl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrbroughton%2Fsibyl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrbroughton%2Fsibyl/lists"}