{"id":13393763,"url":"https://github.com/JSMonk/hegel","last_synced_at":"2025-03-13T19:31:47.765Z","repository":{"id":35455174,"uuid":"153920477","full_name":"JSMonk/hegel","owner":"JSMonk","description":"An advanced static type checker","archived":true,"fork":false,"pushed_at":"2024-01-29T12:23:47.000Z","size":127205,"stargazers_count":2091,"open_issues_count":124,"forks_count":59,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-01-19T00:34:52.712Z","etag":null,"topics":["javascript","type-safety","typeinference"],"latest_commit_sha":null,"homepage":"https://hegel.js.org","language":"JavaScript","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/JSMonk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":null,"patreon":"rage_monk","custom":null}},"created_at":"2018-10-20T15:35:22.000Z","updated_at":"2025-01-17T13:53:00.000Z","dependencies_parsed_at":"2023-01-15T21:45:22.023Z","dependency_job_id":"13bde437-82c1-49d1-bf63-fac626aa03d6","html_url":"https://github.com/JSMonk/hegel","commit_stats":{"total_commits":552,"total_committers":34,"mean_commits":"16.235294117647058","dds":0.4003623188405797,"last_synced_commit":"a92347e6d477ae6280d7e3159103ea8168302c52"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSMonk%2Fhegel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSMonk%2Fhegel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSMonk%2Fhegel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JSMonk%2Fhegel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JSMonk","download_url":"https://codeload.github.com/JSMonk/hegel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243469206,"owners_count":20295709,"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":["javascript","type-safety","typeinference"],"created_at":"2024-07-30T17:00:59.951Z","updated_at":"2025-03-13T19:31:46.320Z","avatar_url":"https://github.com/JSMonk.png","language":"JavaScript","readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"#\" target=\"blank\"\u003e\u003cimg src=\"./logo-dark.svg\" width=\"300\" alt=\"Hegel Logo\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n**Unfortunately, the project is closed and will not be developed anymore. The reasons are described [here](https://jsmonk.github.io/2024-01-29-last-days-of-hegel/).**\n\n[Getting Started](https://hegel.js.org/docs/install) |\n[Documentation](https://hegel.js.org/docs/type-annotations) |\n[Gitter Chat](https://gitter.im/hegel-js/community)\n\nHegel is a type checker for JavaScript with optional type annotations and preventing runtime type errors.\n\n- **No Runtime Type Errors**. Hegel has a strong type system and soundness checks.\n  This means that he finds any `TypeError` that may be thrown in runtime.\n- **Optional Type Annotation**. Hegel has a high-level type inference which gives you the ability to drop a type annotation.\n- **Typed Errors**. Hegel has a mechanism to inference and annotates which errors should be thrown by functions.\n- **Using d.ts as libraries definitions**. Hegel has not a custom language for library typings description. We use a lot of existed `.d.ts` files as the source of typings for any libraries.\n- **Only JavaScript with types**. Hegel has only type syntax, without any additional hard syntax sugar.\n\nTo read more about Hegel, check out [Docs](https://hegel.js.org/docs).\n\n## Benefits over TypeScript\n\n1. **No unexpected runtime errors**\n\nTypeScript never will guarantee that you will not have a Type Error at Runtime. Check [TypeScript non-goals](https://github.com/microsoft/TypeScript/wiki/TypeScript-Design-Goals#non-goals)\npoint 3. Hegel is on the opposite side. We try to implement a strong and sound type system that will guarantee that your program is valid.\n\nAs example ([You can try it in our playground](https://hegel.js.org/try#MYewdgzgLgBGCuBbARgUwE4QFwwILvQEMBPAHgRQwD4YBeGAbQF0BuAKDYHpOYAJVAOaoANgFECIdDgAqxAA6oYAInxEyFNOipKYASwh6woRHMJRdyYYoDuuqAAsYUeYpUES5JJpgAfGNHRdMAFtNlBIWA0MCAB5dABlKEDg7Dx3MgCggV84L2o6XMpMdjYozDjE5IEIBgBGJgKlfmFhEAAaGFkFcXRJAEIlEu4+QREeyRwABV6FdGdlKBAAMV0AD1QAEx0NkFQDMBBYVFX9WCDlADk89Bz4MA3UADMgzZ1S65r6gDpFlfWNgAUtQAlCwgA)):\n\n```typescript\nconst numbers: Array\u003cnumber\u003e = [];\n\n// HegelError: Type \"Array\u003cnumber\u003e\" is incompatible with type \"Array\u003cnumber | string\u003e\"\nconst numbersOrStrings: Array\u003cstring | number\u003e = numbers;\n\nnumbersOrStrings[1] = \"Hello, TypeError!\";\n\n// HegelError: Property \"toFixed\" does not exist in \"Number | undefined\"\nnumbers[1].toFixed(1);\n```\n\n[The same example with TypeScript (v3.8.3)](https://www.typescriptlang.org/play/index.html?ssl=1\u0026ssc=1\u0026pln=6\u0026pc=75#code/MYewdgzgLgBGCuBbARgUwE4QFwwILvQEMBPAHgRQwD4YBeGAbQF0BuAKAHoOYBRAkdDgAqxAA6oYAInxEyFNOiqSYASwiqwoRKMJQVyADYSA7iqgALGFDETpBEuSQKYAHxjR0KsAHMlbUJCw8hgQAPLoAMpQnj7YePZkHl7ernBO1HRplJjswZjhUTHeEAwAjEyZkgASqAYGIAA0MCLifOgCAISS7Fy8-IIwAArt4ujWUlAgAGIqAB6oACbKCyCo6mAgsKizarBeUgBy6eip8GALqABmXovKbHkl5QB0kzPzCwAUpQCULEA)\ncompiles without any error, but you will have 2 `TypeError` in runtime.\n\n2. **Ability to skip type annotation**\n\nHegel is targeting at really powerful type inference which gives an ability to write fewer type annotations.\n\nAs example ([You can try it in our playground](https://hegel.js.org/try#MYewdgzgLgBADgJxAWwJYVQMwJ4wLwyZj4B8MAhggOakwAKSaEApgHQLMQgA2AbswAoiAylQCUYgNwAoUJFioAJvniN0WbAIAetLVOkB6AzACCYZQCIArnDjMEAZSgILMAO6pu3GACNmMVDBMew5lcggYCwYUdGYAHmgEQKoSC1lwaBgbO0dnFSUBCwBJWA8vX39A4IRQizFWKAALZjABRNpEhpAAVVt7AGFwwQlJIA)):\n\n```javascript\nconst promisify = (fn) =\u003e (arg) =\u003e Promise.resolve(fn(arg));\n\nconst id = promisify((x) =\u003e x);\n\n// And \"upperStr\" will be inferred as \"Promise\u003cstring\u003e\"\nconst upperStr = id(\"It will be inferred\").then((str) =\u003e str.toUpperCase());\n```\n\n[The same example with TypeScript (v3.8.3)](https://www.typescriptlang.org/play/index.html?ssl=6\u0026ssc=75\u0026pln=6\u0026pc=45#code/PTAEAkFMHNIG1AdwJZwcgdgM0gJ1AEQAOuA9gLbIDOyWAngaAIZWEA8A+gI4A0oHAYwB8AChGCAlKAC8Q-lymzQ4gYrkAFMpSqROXIQQBQA0hioAXUCQrVadGaCwYZcprmgvQmmzoB0uSCpSOAA3SBEnETdoCQkAbkMQUAAVAAs8SD4oWAQUNFBMHHwCTmEVNS8tal1BA2NTCwKAEwdrbTsRAA9PTvjEsABBDBaCAFciIjwAZXNcRjyEACNIAuw8AJaWQm9tXQtcTGg6kzNLccncGfxpZpECAElLBdBl1aKNgglfc3SMEX3PPtvqQAKoTPAAYRY4VicSAA)\nwill throw 2 errors and inference `upperStr` as `Promise\u003cany\u003e`.\n\n3. **Typed Errors**\n\nHegel gives you information about errors that may be thrown by functions/methods.\n\n[Example of error type inference](https://hegel.js.org/try#GYVwdgxgLglg9mABAQwM6oKYCcoAU6oywBuGAciALYBG2AFMcgDYgYCUiA3gFCJ+IxgiOlACeABwxwhjFhkQBCALxLEAIjBVaWNRx78DiKAAsscAO6IwGSwBUJGAKJYzWOmoDiMUkmRYA5lQYYFACqFZwochWWtgKugDcvPwAvsl8gsKyrIgAPIgADHrphiZmltaWAErIYP5OLnBunt7BMTTYYRFRiOIERK3t2vFsSQZpKUA)\n\n```javascript\n// If you hover at function name you will see it type as \"(unknown) =\u003e undefined throws RangeError | TypeError\"\nfunction assertPositiveNumber(value) {\n  if (typeof value !== \"number\") {\n    throw new TypeError(\"Given argument is not a number!\");\n  }\n  if (value \u003c 0) {\n    throw new RangeError(\"Given number is not a positive number!\");\n  }\n}\n```\n\nAs you understand, you will have the same error type in `try-catch` block.\n[Example](https://hegel.js.org/try#GYVwdgxgLglg9mABAQwM6oKYCcoAU6oywBuGAciALYBG2AFMcgDYgYCUiA3gFCJ+IxgiOlACeABwxwhjFhkQBCALxLEAIjBVaWNRx78DiKAAsscAO6IwGSwBUJGAKJYzWOmoDiMUkmRYA5lQYYFACqFZwochWWtgKugDcvPwAvsl8gsKyrIgAPIgADHrphiZmltaWAErIYP5OLnBunt7BMTTYYRFRiOIERK3t2vFsSQZpadxQWKJcJWiYOPiEJOSxbgAso9wpiBDIUBDGdOxzBgD054gAEhj1TAJgwNjBEPIABhjvRg4o4Wo1OoNVyIAA+iHskmcIPB4AA1mALGA1DsgA):\n\n```javascript\ntry {\n  assertPositiveNumber(4);\n} catch (e) {\n  // Hegel inference `e` type as \"RangeError | TypeError | unknown\"\n}\n```\n\n[The same example with TypeScript (v3.8.3)](https://www.typescriptlang.org/play/index.html#code/GYVwdgxgLglg9mABAQwM6oKYCcoAU6oywBuGAciALYBG2AFMcgDYgYCUiA3gFCJ+IxgiOlACeABwxwhjFhkQBCALxLEAIjBVaWNRx78DiKAAsscAO6IwGSwBUJGAKJYzWOmoDiMUkmRYA5lQYYFACqFZwochWWtgKugDcvPwAvsl8gsKyrIgAPIgADHrphiZmltaWAErIYP5OLnBunt7BMTTYYRFRiOIERK3t2vFsSQZpadxQWKJcJWiYOPiEJOSxbgAso9wpiBDIUBDGdOxzBgD054gAEhj1TAJgwNjBEPIABhjvRg4o4Wq1URqHZAA)\nwill throw one error and `e` type will be `any`.\n\n## Benefits over Flow\n\n1. **No custom library definition language**\n\nFlow.js has custom library definition languages and doesn't support the most popular TypeScript \"d.ts\" format. But for Hegel TypeScript \"d.ts\" it the only way to create type definition for library. So, every library which has TypeScript definitions should work with Hegel.\n\n2. **Better type inference**\n\nHegel inferences function type by function declaration when Flow inferences function type by usage.\nAs example ([You can try it in our playground](https://hegel.js.org/try#MYewdgzgLgBAlgExgXhgDxQPnQbgFAD0BMAKgJ4AOApjCAGYwBEYArgLaMwBuAhgE5weAIwA2NOBCas2Qqn0Z4xsaSngIAFABYAlPiKlKNek2jzu-QaPGTGpuGADmCpTFOrE6xpsa68QA)):\n\n```javascript\nconst id = (x) =\u003e x;\n// Hegel inference type of \"num\" variable is \"number\"\nlet num = id(4);\n// And type of \"str\" as \"string\"\nlet str = id(\"4\");\n```\n\n[The same example with Flow (v0.123.0)](https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBjOA7AzgFzAEsATMAXjAA8KA+agblWGDABUBPABwFMw4oYAETYArgFshYAG4BDAE5FZAIxh8iuYWPHKe8oajWFtFYiQAUAFgCUTFu258BwgvpkKlq9ZqGui2AHMDIzBXU1JzIUshW1QgA)\nwill inference both `num` and `str` as `number | string`.\n\n3. **Typed Errors**\n\nHegel gives you information about errors that may be thrown by functions/methods.\n\n[Example of error type inference](https://hegel.js.org/try#GYVwdgxgLglg9mABAQwM6oKYCcoAU6oywBuGAciALYBG2AFMcgDYgYCUiA3gFCJ+IxgiOlACeABwxwhjFhkQBCALxLEAIjBVaWNRx78DiKAAsscAO6IwGSwBUJGAKJYzWOmoDiMUkmRYA5lQYYFACqFZwochWWtgKugDcvPwAvsl8gsKyrIgAPIgADHrphiZmltaWAErIYP5OLnBunt7BMTTYYRFRiOIERK3t2vFsSQZpKUA)\n\n```javascript\n// If you hover at function name you will see it type as \"(unknown) =\u003e undefined throws RangeError | TypeError\"\nfunction assertPositiveNumber(value) {\n  if (typeof value !== \"number\") {\n    throw new TypeError(\"Given argument is not a number!\");\n  }\n  if (value \u003c 0) {\n    throw new RangeError(\"Given number is not a positive number!\");\n  }\n}\n```\n\nAs you understand, you will have the same error type in `try-catch` block.\n[Example](https://hegel.js.org/try#GYVwdgxgLglg9mABAQwM6oKYCcoAU6oywBuGAciALYBG2AFMcgDYgYCUiA3gFCJ+IxgiOlACeABwxwhjFhkQBCALxLEAIjBVaWNRx78DiKAAsscAO6IwGSwBUJGAKJYzWOmoDiMUkmRYA5lQYYFACqFZwochWWtgKugDcvPwAvsl8gsKyrIgAPIgADHrphiZmltaWAErIYP5OLnBunt7BMTTYYRFRiOIERK3t2vFsSQZpadxQWKJcJWiYOPiEJOSxbgAso9wpiBDIUBDGdOxzBgD054gAEhj1TAJgwNjBEPIABhjvRg4o4Wo1OoNVyIAA+iHskmcIPB4AA1mALGA1DsgA):\n\n```javascript\ntry {\n  assertPositiveNumber(4);\n} catch (e) {\n  // Hegel inference `e` type as \"RangeError | TypeError | unknown\"\n}\n```\n\n[The same example with Flow (v0.123.0)](https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVUCuA7AxgFwEs5swBDAZwoFMAnfABTgsKIDdqA5TAWwCM6ACjZkYmagEowAb1Rh5YQlDCD8ATwAO1OMpFjqYAIQBeY2ABE2XgNrmpshY7D4AFrURhs1JABVN1AFFad1pBcwBxQg5SMloAc15qbHxFCk84FLJPazpDOwBuOQUAXyL5JRU9cTAAHjAABnsyp1d3JC8kACUybDjA4LhQiKik7P46VPTMsA1mVhGxmzyJQsdS0tR8WjUZZsoaeiYWdi4c0IBaACYV1GKwXDJ8XBdBSV3HYGAwAAlqPphFNgoHQkrgDAADajg5z+chpczUHgadTmW5AA)\nwill inference `e` type as `empty`.\n\n## Installing\n\n**Step 1**: check your [Node.js](https://nodejs.org/en/) version:\n\n```bash\n$ node -v\nv12.0.0\n```\n\nHegel was developed for current LTS version of [Node.js (12.16.1)](https://nodejs.org/en/). So, you need to have at least 12 version.\n\nIf you have less than 12 version of [Node.js](https://nodejs.org/en/) you may change it to 12 or latest by [`nvm`](https://github.com/nvm-sh/nvm).\n\n**Step 2**: install `@hegel/cli` with npm globally or locally:\n\n```bash\n# globally\n$ npm install -g @hegel/cli\n\n# locally\n$ npm install -D @hegel/cli\n```\n\n**Step 3**. You already can use it into your JavaScript project:\n\n```bash\n# globally\n$ hegel\nNo errors!\n\n# locally\n$ npx hegel\nNo errors!\n```\n\n\u003e Hegel has a zero-configuration, but if you want to change settings see [Configuration Section](https://hegel.js.org/docs/configuration).\n\n**Step 4**. Hegel is already configured, but, you need to compile your project to plain JavaScript.\n\n- If you use [Babel](https://babeljs.io/):\n  Add into `.babelrc` file (or create `.babelrc` file at the root of your project with) next content:\n\n  ```json\n  {\n    \"presets\": [[\"@babel/preset-flow\", { \"all\": true }]]\n  }\n  ```\n\n  And install `@babel/preset-flow`\n\n  ```bash\n  $ npm i -D @babel/core @babel/cli @babel/preset-flow\n  ```\n\n  Add script inside your package.json:\n\n  ```json\n  {\n    \"name\": \"your-project\",\n    \"scripts\": {\n      \"build\": \"babel directory_with_your_project_files/ -d compilation_destination_directory/\"\n    }\n  }\n  ```\n\n- If you don't use [Babel](https://babeljs.io/):\n  The same as Flow, you can use [flow-remove-types](https://www.npmjs.com/package/flow-remove-types).\n\n  Install `flow-remove-types`:\n\n  ```bash\n  $ npm i -D flow-remove-types\n  ```\n\n  And add next script inside your `package.json` `scripts` section:\n\n  ```json\n  {\n    \"scripts\": {\n      \"build\": \"flow-remove-types directory_with_your_project_files/ --out-dir compilation_destination_directory/ --all\"\n    }\n  }\n  ```\n\n**Finally**. You can compile your project by:\n\n```bash\n$ npm run build\n```\n\n## Project Overview\n\nThere are few separated packages in Hegel project:\n\n- [@hegel/core](https://github.com/JSMonk/hegel/tree/master/packages/core): the main logic of analysis.\n- [@hegel/cli](https://github.com/JSMonk/hegel/tree/master/packages/cli): CLI logic.\n- [@hegel/typings](https://github.com/JSMonk/hegel/tree/master/packages/typings): typings for browser or node.js environment and for default global environment\n- [@hegel/language-server](https://github.com/JSMonk/hegel/tree/master/packages/language-server): language Server (which currently work with VS Code)\n- [@hegel/docs](https://github.com/JSMonk/hegel/tree/master/packages/docs): documentation\n\n## Building Hegel from source\n\nYou will need to install [Git](https://git-scm.com/downloads), nodejs, npm and yarn\n\nit is HIGHLY RECOMMENDED to install nodejs (and npm) with [nvm](https://github.com/creationix/nvm) and then yarn with npm like so `npm -g i yarn`\n\nrequired versions of sayed software are listed below\n\n```yaml\nnode: ^12.16.3\nnpm: ^6.14.4\nyarn: ^1.22.4\n```\n\nOpen Terminal and copy paste following commands\n\n```sh\n# clone the repo\ngit clone git@github.com:JSMonk/hegel.git\n\n# cd into the repo\ncd hegel\n\n# install all dependencies\nyarn\n\n# build core and cli\nyarn build\n```\n\n## Tests\n\nCurrently, all tests are written for [@hegel/core](https://github.com/JSMonk/hegel/tree/master/packages/core), so, if you will change code inside [@hegel/core](https://github.com/JSMonk/hegel/tree/master/packages/core) package, you can run tests by:\n\n```sh\nyarn test\n```\n\n## License\n\nHegel is MIT-licensed ([LICENSE](https://github.com/JSMonk/hegel/blob/master/LICENSE)).\n","funding_links":["https://patreon.com/rage_monk"],"categories":["JavaScript","\u003e 1K ⭐️"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJSMonk%2Fhegel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJSMonk%2Fhegel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJSMonk%2Fhegel/lists"}