{"id":13520465,"url":"https://github.com/pvdz/escaya","last_synced_at":"2026-01-08T16:47:00.366Z","repository":{"id":141909448,"uuid":"274594890","full_name":"pvdz/escaya","owner":"pvdz","description":"A blazing fast 100% spec compliant, self-hosted javascript parser written in Typescript","archived":false,"fork":false,"pushed_at":"2020-06-24T06:53:08.000Z","size":272,"stargazers_count":0,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-06T13:34:39.344Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pvdz.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-06-24T06:41:42.000Z","updated_at":"2021-05-21T13:31:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"82556f2d-1f0c-487b-9cdc-62db8ae0bf71","html_url":"https://github.com/pvdz/escaya","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvdz%2Fescaya","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvdz%2Fescaya/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvdz%2Fescaya/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pvdz%2Fescaya/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pvdz","download_url":"https://codeload.github.com/pvdz/escaya/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246443543,"owners_count":20778251,"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":[],"created_at":"2024-08-01T05:02:21.624Z","updated_at":"2026-01-08T16:47:00.340Z","avatar_url":"https://github.com/pvdz.png","language":null,"funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eEscaya\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e An 100% spec compliant, self-hosted javascript parser written in Typescript.\u003c/p\u003e\n\n\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://lgtm.com/projects/g/escaya/escaya/context:javascript\"\u003e\u003cimg src=\"https://img.shields.io/lgtm/grade/javascript/g/escaya/escaya.svg?logo=lgtm\u0026logoWidth=18\" alt=\"GitHub license\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/escaya/escaya/blob/master/LICENSE.md\"\u003e\u003cimg src=\"https://img.shields.io/github/license/escaya/escaya.svg\" alt=\"License\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n**Work in progress**\n\nStill to early to release the source file to public, but a demo can be found [here](https://escaya.github.io/escaya/).\n\n\n## Features\n\n* Conforms to the standard ECMAScript® 2021 (ECMA-262 11th Edition) language specification\n* Support for additional ECMAScript features for Web Browsers\n* Optionally track syntactic node locations\n* Emits an ECMAScript® 2021 compatible abstract syntax tree\n* Error recovery mode with incremental parsing support\n* JSON friendly\n* No backtracking\n* Low memory usage\n* Optimized for use on handheld devices such as a mobile phone or tablet\n* Very well tested (~15 000 unit tests with full code coverage)\n* Lightweight - ~84 KB minified\n\n## API\n\nEscaya generates it's own `AST` that is close to the [ECMAScript® 2021 specs](https://tc39.es/ecma262/index.html), and can be used to perform [syntactic analysis](https://en.wikipedia.org/wiki/Parsing) (parsing) of a JavaScript program, and with `ES2015` and later a JavaScript program can be either [a script or a module](https://tc39.github.io/ecma262/index.html#sec-ecmascript-language-scripts-and-modules).\n\nThis is the available options:\n\n```js\n{\n  // Enable stage 3 support (ESNext)\n  next?: boolean;\n  // Disable web compatibility\n  disableWebCompat?: boolean;\n  // Enable line/column location information start and end offsets to each node\n  loc?: boolean;\n  // Allow return in the global scope\n  globalReturn?: boolean;\n  // Enable implied strict mode\n  impliedStrict?: boolean;\n  // Adds a source attribute in every node’s loc object when the locations option is `true`\n  source?: string;\n  // Enable parsing in module goal in error recovery mode\n  module?: boolean;\n}\n```\n\nExample usage:\n\n```ts\n\nimport { parseScript, parseModule, parse } from './escaya';\n\nparseScript('({x: [y] = 0} = 1)');\n\nparseModule('({x: [y] = 0} = 1)', { impliedStrict: true });\n\n```\n\n\n## Error recovery\n\nWhen Escaya parser is given an input that does not represent a valid JavaScript program, it throws an exception. If parsing in\nrecovery mode, the parser will continue parsing and produce a syntax tree.\n\nHowever, Escaya will continue to do a full parse for every keystroke. To avoid this you can enable incremental parsing. This is best demonstrated with an example.\n\n```ts\n\nimport { recovery, update } from './escaya';\n\nconst rootNode = recovery('(foo);', 'filename.js', { module: true }); \n\nconst ast = update(rootNode, '=\u003e bar;', 'filename.js', { span: { start: 6, length: 0 }, newLength: 7 })\n\n```\n\nNow when incremental parsing have been enabled, Escaya will reuse nodes from the old tree if possible.\n\n### Options\n\nThe options for the recovery mode  are about the same as  for `parseScript` and `parseModule` except you have to enable `{module: true}` if parsing in module goal.\n\nNo options can be set during an incremental update because it's only possible to reuse a node if it was parsed in the same context that parser are currently in. \n\n### AST\n\nOne of the design goals for Escaya has been that the AST shouldn't change. It should be the same either you are parsing in `normal mode` or `recovery mode`.But there are a couple of exceptions. In `recovery mode` you are creating a `RootNode` instead of either a `Module` or `Script`, and this `RootNode` has additional information such as diagnostics, context masks and mutal parser flags that you *carry over* from the recovery mode to the incremental parsing and let you continue to parse in the same context that you are currently in unless you set a strict directive on the `RootNode`.\n\nIf you do this, Escaya will parse in strict mode and you will not be able to recover any nodes from the old tree if you were first parsing in *sloppy mode*, because\nit's only possible to reuse a node if it was parsed in the same context that the parser are currently in.\n\n## Escaya AST\n\nThe abstract syntax tree (AST) used by `Escaya` represents the structure of an ECMAScript program as a tree and conforms to the [ECMAScript® 2021 specification](https://tc39.es/ecma262/index.html). The AST have been designed for performance, and it nearly eliminates the chance of accidentally creating an AST that does not represent an ECMAScript program and it consumes less bytes than the AST produced by `ESTree` and `Babel`.\n\nThe `Escaya AST` doesn't try to follow the SpiderMonkey-compatible standard that `ESTree` strictly follows, and it distinguish `Identifier` from `IdentifierPattern` and makes it easier to calculate the free variables of a program. \n\n## CLI\n\nThe CLI is still a TODO, but will parse Escaya in recovery mode and use the diagnostic messages to create an nice output so that you are always informed of invalid syntax and you can correct this.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpvdz%2Fescaya","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpvdz%2Fescaya","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpvdz%2Fescaya/lists"}