{"id":13177,"library":"fastparse","title":"fastparse: Simple Regex-based State Machine Parser","description":"The `fastparse` library, currently at version 1.1.2, offers a very simple and efficient state machine-based parser driven entirely by regular expressions. It's designed for lightweight text processing tasks, not complex language parsing, and excels at extracting specific patterns from structured text or simple domain-specific languages. The library's core mechanism involves compiling a user-defined state machine description into optimized regular expressions for each state, leveraging the native JavaScript regex engine for high-performance pattern matching. This approach makes it exceptionally fast for its intended use cases. While its release cadence appears slow, suggesting a stable and mature project rather than one with frequent new feature development, its explicit simplicity is a key differentiator, focusing on minimal overhead and direct regex delegation. This makes it an ideal choice when a full-fledged AST-generating parser is overkill, and targeted extraction of information is the primary goal.","status":"maintenance","version":"1.1.2","language":"javascript","source_language":"en","source_url":"https://github.com/webpack/fastparse","tags":["javascript","parser","regexp"],"install":[{"cmd":"npm install fastparse","lang":"bash","label":"npm"},{"cmd":"yarn add fastparse","lang":"bash","label":"yarn"},{"cmd":"pnpm add fastparse","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library primarily exports `Parser` as a default export, though older bundlers might handle CommonJS `require` differently.","wrong":"import { Parser } from 'fastparse';","symbol":"Parser","correct":"import Parser from 'fastparse';"},{"note":"CommonJS usage as shown in the original documentation example.","symbol":"Parser","correct":"const Parser = require('fastparse');"},{"note":"`Parser` is a class and must be instantiated with `new`.","wrong":"const parser = Parser(description);","symbol":"ParserInstance","correct":"const parser = new Parser(description);"}],"quickstart":{"code":"const Parser = require(\"fastparse\");\n\n// A simple parser that extracts @licence ... from comments in a JS file\nconst parser = new Parser({\n\t// The \"source\" state\n\t\"source\": {\n\t\t// matches comment start\n\t\t\"/\\\\*\": \"comment\",\n\t\t\"//\": \"linecomment\"\n\t},\n\t// The \"comment\" state\n\t\"comment\": {\n\t\t\"\\\\*/\": \"source\",\n\t\t\"@licen[cs]e\\\\s((?:[^*/\\n]|\\\\*+[^*/\\n])*)?\": function(match, licenseText) {\n\t\t\tthis.licences.push(licenseText ? licenseText.trim() : '');\n\t\t}\n\t},\n\t// The \"linecomment\" state\n\t\"linecomment\": {\n\t\t\"\\n\": \"source\",\n\t\t\"@licen[cs]e\\\\s(.*)\": function(match, licenseText) {\n\t\t\tthis.licences.push(licenseText.trim());\n\t\t}\n\t}\n});\n\nconst sourceCode = `\n/* @license MIT */\n// @licence Apache\nconst x = 1;\n/* Some other comment\n * @license BSD\n */\n`;\n\nconst licences = parser.parse(\"source\", sourceCode, { licences: [] }).licences;\n\nconsole.log(licences);\n// Expected output: [ 'MIT', 'Apache', 'BSD' ]","lang":"javascript","description":"Demonstrates how to define a state machine using regular expressions and transition functions to extract license information from a JavaScript source code string."},"warnings":[{"fix":"Ensure regex patterns within a state are mutually exclusive where possible, or explicitly order them such that the most specific patterns appear first, acknowledging the potential for engine-specific behavior if order preservation is not guaranteed.","message":"The parser's matching order for regular expressions within a state historically relied on the JavaScript `description` object's key order being preserved. While modern JavaScript engines (ES2015+) generally guarantee insertion order for string keys, reliance on this implicit behavior in older environments or with non-compliant engines could lead to non-deterministic parsing behavior if regex patterns overlap.","severity":"breaking","affected_versions":"<=1.1.2"},{"fix":"Carefully design and test your state machine. Place more specific or restrictive regular expressions before more general ones within the same state definition to ensure correct matching precedence.","message":"If multiple regular expressions within a single state can match the same part of the input string, the one defined earlier in the state object takes precedence. Incorrect ordering can lead to unintended parsing paths, incomplete matches, or infinite loops if no transition is made.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Simplify regular expressions where possible. Avoid nested quantifiers and excessive backtracking. Thoroughly test regex performance with various input sizes and edge cases, especially if patterns are derived from external sources.","message":"`fastparse` delegates parsing to native JavaScript regular expressions. While efficient, using overly complex or backtracking-prone regex patterns (e.g., `(a+)*`) can lead to exponential time complexity, causing performance bottlenecks or potential ReDoS (Regular Expression Denial of Service) vulnerabilities, especially when processing untrusted input.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Document the expected properties and modifications for the `context` object. Consider defensive programming practices, such as deep cloning sensitive parts of the context if immutability is desired for certain operations.","message":"The `context` object passed to `parser.parse()` is directly accessible as `this` within transition functions, allowing for stateful modifications. While powerful, this mutable shared context can introduce side effects and make debugging challenging if not managed carefully, especially in complex parsers.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using `new Parser(...)` for instantiation. If using ES modules, `import Parser from 'fastparse';`. If using CommonJS, `const Parser = require('fastparse');`.","cause":"Attempting to instantiate `Parser` without the `new` keyword, or an incorrect module import pattern (e.g., using named import for a default export, or CommonJS `require` with `new` on the module object itself).","error":"TypeError: Parser is not a constructor"},{"fix":"Verify that the initial `context` object passed to `parser.parse(initialState, parsedString, context)` contains all the properties your transition functions expect to use, e.g., `{ licences: [] }`.","cause":"A transition function attempts to access or modify a property on the `this` (context) object that was not initialized or provided in the `context` argument to `parser.parse()`.","error":"TypeError: Cannot read properties of undefined (reading 'push')"},{"fix":"Review the problematic regular expression in your state definition. Escape all special regex characters with a double backslash (`\\\\`) if you intend for them to be matched literally in the input string.","cause":"One of the regular expressions defined in your state machine description is syntactically incorrect, often due to unescaped special characters (e.g., `.` `*` `+` `?` `(` `)` `[` `]` `{` `}` `|` `^` `$` `\\` `/`) when they are intended to be literal characters.","error":"SyntaxError: Invalid regular expression: /.../: Nothing to repeat"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}