or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-flow-parser

JavaScript parser written in OCaml that produces ESTree AST with optional Flow type annotations support

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/flow-parser@0.280.x

To install, run

npx @tessl/cli install tessl/npm-flow-parser@0.280.0

index.mddocs/

Flow Parser

Flow Parser is a JavaScript parser written in OCaml and compiled to JavaScript. It produces an Abstract Syntax Tree (AST) that conforms to the ESTree specification and mostly matches what esprima produces. The parser serves as the core parsing engine for Flow (Facebook's static type checker for JavaScript) but can be used independently to parse JavaScript code with optional Flow type annotations.

Package Information

  • Package Name: flow-parser
  • Package Type: npm
  • Language: JavaScript (compiled from OCaml)
  • Installation: npm install flow-parser

Core Imports

Node.js (CommonJS):

const parser = require('flow-parser');

Browser:

<script src="flow_parser.js"></script>
<script>
  // The global 'flow' object is available
  const ast = flow.parse('code', {});
</script>

Basic Usage

const parser = require('flow-parser');

// Parse JavaScript with Flow types enabled (default)
const ast = parser.parse('let x: number = 42;', { types: true });

// Parse plain JavaScript without type annotations
const ast2 = parser.parse('let x = 42;', { types: false });

// Parse with all comments and tokens included
const astWithTokens = parser.parse('/* comment */ let x = 1 + 1;', {
  types: true,
  comments: true,
  tokens: true
});

console.log(ast.type); // "Program"
console.log(ast.errors); // Array of parse errors (if any)

Capabilities

Parse Function

The primary API for parsing JavaScript source code with comprehensive configuration options.

/**
 * Parse JavaScript source code and return an ESTree-compliant AST
 * @param content - JavaScript source code to parse
 * @param options - Optional configuration object controlling parser behavior
 * @returns ESTree AST object with additional Flow-specific properties
 */
function parse(content: string, options?: ParseOptions): AST;

interface ParseOptions {
  // Basic parsing options
  types?: boolean;           // Enable Flow type parsing (default: true)
  use_strict?: boolean;      // Treat as strict mode (default: false)
  comments?: boolean;        // Attach comments to AST nodes (default: true)
  all_comments?: boolean;    // Include all comments list (default: true)
  tokens?: boolean;          // Include parsed tokens (default: false)
  
  // Language feature options
  enums?: boolean;           // Enable Flow enums (default: false)
  pattern_matching?: boolean; // Enable Flow match expressions/statements (default: false)
  components?: boolean;      // Enable Flow component syntax (default: false)
  assert_operator?: boolean; // Enable assert operator (default: false)
  esproposal_decorators?: boolean; // Enable decorators (default: false)
}

interface AST {
  type: "Program";
  body: any[];               // Array of ESTree Statement nodes
  comments?: Comment[];      // All comments when all_comments is true
  tokens?: Token[];          // All tokens when tokens is true
  errors: ParseError[];      // Parse errors encountered
  sourceType: "script" | "module";
  // Additional ESTree properties...
}

interface ParseError {
  message: string;
  loc: SourceLocation;
  // Error-specific properties
}

interface Comment {
  type: "Block" | "Line";
  value: string;
  loc: SourceLocation;
}

interface Token {
  type: string;
  value: string;
  loc: SourceLocation;
}

interface SourceLocation {
  start: Position;
  end: Position;
}

interface Position {
  line: number;   // 1-based
  column: number; // 0-based
}

Usage Examples:

const parser = require('flow-parser');

// Basic parsing with type support
const ast = parser.parse(`
  type User = {
    name: string,
    age: number
  };
  
  function greet(user: User): string {
    return \`Hello \${user.name}!\`;
  }
`, { types: true });

// Parse with comprehensive output
const detailedAst = parser.parse(`
  // This is a comment
  const items = [1, 2, 3];
  const doubled = items.map(x => x * 2);
`, {
  types: false,
  comments: true,
  all_comments: true,
  tokens: true
});

// Access parse results
console.log('AST type:', detailedAst.type);
console.log('Parse errors:', detailedAst.errors.length);
console.log('Comments found:', detailedAst.comments?.length || 0);
console.log('Tokens found:', detailedAst.tokens?.length || 0);

// Handle parse errors
const invalidCode = parser.parse('let x = ;', { types: false });
if (invalidCode.errors.length > 0) {
  invalidCode.errors.forEach(error => {
    console.log(`Parse error at line ${error.loc.start.line}: ${error.message}`);
  });
}

Flow-specific Language Features:

// Enable Flow enums
const enumAst = parser.parse(`
  enum Status {
    PENDING,
    COMPLETE,
    FAILED
  }
`, { enums: true });

// Enable Flow match expressions
const matchAst = parser.parse(`
  const result = match (value) {
    1 => "one",
    2 => "two",
    _ => "other"
  };
`, { pattern_matching: true });

// Enable Flow components
const componentAst = parser.parse(`
  component Button(text: string) {
    return <button>{text}</button>;
  }
`, { components: true });

// Enable decorators
const decoratorAst = parser.parse(`
  class MyClass {
    @observable value = 0;
  }
`, { esproposal_decorators: true });

Error Handling

The parser is designed to be fault-tolerant and will attempt to parse as much of the input as possible:

const parser = require('flow-parser');

// Parse code with syntax errors
const ast = parser.parse(`
  let valid = 'this works';
  let invalid = ;  // syntax error
  let alsoValid = 'this also works';
`, { types: false });

// The AST is still returned with partial results
console.log('AST generated:', ast.type === 'Program');
console.log('Errors found:', ast.errors.length);

// Examine errors
ast.errors.forEach((error, index) => {
  console.log(`Error ${index + 1}:`);
  console.log(`  Message: ${error.message}`);
  console.log(`  Location: Line ${error.loc.start.line}, Column ${error.loc.start.column}`);
});

Browser Compatibility

The parser works in both Node.js and browser environments:

<!DOCTYPE html>
<html>
<head>
  <script src="node_modules/flow-parser/flow_parser.js"></script>
</head>
<body>
  <script>
    // Use the global 'flow' object
    const ast = flow.parse('const x = 42;', { types: false });
    console.log('Parsed successfully:', ast.type === 'Program');
    
    // All the same options are available
    const typedAst = flow.parse('const x: number = 42;', { 
      types: true,
      comments: true 
    });
  </script>
</body>
</html>

Performance Considerations

  • The parser is optimized for parsing speed and memory efficiency
  • For large codebases, consider parsing files individually rather than concatenating
  • Token generation (tokens: true) increases memory usage and parsing time
  • Comment processing is relatively lightweight but can be disabled if not needed
// Optimal performance configuration for large files
const ast = parser.parse(largeCodebase, {
  types: true,      // Keep if you need Flow types
  comments: false,  // Disable if comments aren't needed
  all_comments: false,
  tokens: false     // Disable unless specifically needed
});