For AI agents: the complete documentation index is available at /tc39-atlas/en/llms.txt, the full documentation bundle is available at /tc39-atlas/en/llms-full.txt, and this page is available as Markdown at /tc39-atlas/en/proposals/proposal-hashbang.md.
  • English
  • Hashbang Grammar S4

    Proposal details
    Proposal overview

    This proposal standardizes hashbang (#!) comments at the start of JS source files by moving the stripping responsibility from CLI hosts to JS engines. It allows hashbang only at the beginning of Script or Module goals, supports eval but not Function, and handles BOM interaction.

    Note

    The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.

    Hashbang Grammar

    This proposal is to match de-facto usage in some CLI JS hosts that allow for Shebangs / Hashbang. Such hosts strip the hashbang in order to generate valid JS source texts before passing to JS engines currently. This would move the stripping to engines, it does unify and standardize how that is done.

    Example

    #!/usr/bin/env node
    // in the Script Goal
    'use strict';
    console.log(1);
    #!/usr/bin/env node
    // in the Module Goal
    export {};
    console.log(1);

    Status

    Why Hashbang instead of Shebang

    Hash is commonly associated with modern terms involving # such as hashtag. In addition for discoverability, the term "hash sign" is used for # but "she sign" is not.

    Why only at the start of a Source Text

    Hashbang comments are only valid at the start of a file for interpretters in various CLI environments. There is no gain for the intended usage by allowing it in other places and in fact could lead to confusion since it would not be picked up by CLI environments. Additionally by allowing Hashbang in other places it overlaps a grammar space for #! if it is an inifix binary expression of some kind. Use // if you want line comments elsewhere.

    Does the hashbang syntax work within eval / Function?

    Hashbang comments are only avilable at the start of a Script or Module parsing goal. Since eval uses Script it does support Hashbang comments. Since Function uses FunctionBody, it does not.

    Interaction with byte-order mark

    A byte-order mark (BOM) character at the beginning of a source text will prevent a subsequent #! from being interpreted as a hashbang. However, web browsers strip this character as part of fetching external scripts or modules (in decode or UTF-8 decode respectively), which happens before the text is interpreted as ECMAScript. As such, in browsers a BOM character can precede a #! in an external script or module, but not an inline one.

    Generally speaking, the BOM character is assumed to be handled by the host, and is not given special treatment by this proposal.

    Existing Notes from Meetings