Promptfoopromptfoo 0.124.1 · Node 24 · Python 3
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
33 small wins to finish your pathNext lesson →

A JavaScript assertion

A JavaScript assertion is the same idea as the Python one in Node: type: javascript with value: file://assert.js, exporting a function that returns a verdict.

Last updated: 15 Oct, 2026 · Promptfoo 0.124.1

Promptfoo runs on Node, so a check written in JavaScript needs nothing extra installed. The file exports one function, promptfoo calls it with the answer and a context, and it returns either a boolean or a {pass, score, reason} object, the same two shapes the Python check uses.

The exported function

The entry point is the module's export itself, called as (output, context). This check pulls month names out of the answer and reports which it found. The syntax is plain Node, so string and array methods are all there.

javascript
// a JavaScript assertion returns {pass, score, reason} (or a plain true/false)
const MONTHS = ["January", "February", "March", "April", "May", "June"];

module.exports = (output, context) => {
  const named = MONTHS.filter((m) => output.includes(m));
  return {
    pass: named.length > 0,
    score: named.length ? 1 : 0,
    reason: named.length ? `names ${named.join(", ")}` : "no month named",
  };
};

The config points a javascript assertion at the file, across two questions: one the bot answers with a date, one it misses.

yaml
providers:
  - file://support_bot.py
prompts:
  - "{{question}}"
tests:
  - vars: { question: "Where is order A17?" }
    assert:
      - type: javascript
        value: file://assert.js
  - vars: { question: "Is the store open on Sunday?" }
    assert:
      - type: javascript
        value: file://assert.js
Project files used on this pageThis lesson builds on a project from earlier lessons. The code below imports these files. Click a file to see its code, or follow the link to the lesson that wrote it. To run the code yourself, keep them in the same folder.
View the code here
show.py
# read out.json: each answer, its checks, and any metric scores
import json

for r in json.load(open("out.json"))["results"]["results"]:
    print(r["response"]["output"], "->", "PASS" if r["success"] else "FAIL")

    for c in r["gradingResult"]["componentResults"]:
        print("  ", "pass" if c["pass"] else "FAIL", c["assertion"]["type"], "-", c["reason"])

    if r["namedScores"]:
        scores = {k: round(v, 3) for k, v in r["namedScores"].items()}
        print("   metrics", scores, "| test score", round(r["score"], 3))
support_bot.py
# the shop support bot: find the answer in the handbook, or say it is missing
HANDBOOK = {
    "a17": "Order A17 shipped on 3 March by courier.",
    "refund": "Refunds take five working days.",
}

def call_api(prompt, options, context):
    asked = prompt.lower()                      # the rendered prompt is the question
    for key, line in HANDBOOK.items():
        if key in asked:
            return {"output": line}
    return {"output": "I could not find that in the handbook."}
ExampleThe JavaScript check passes on the dated answer, fails on the miss
promptfoo eval -c jsassert.yaml -o out.json --no-table >/dev/null 2>&1
python3 show.py

The JavaScript entry point

PartWhat it is
The exportmodule.exports = (output, context) => ...
outputThe answer string to check
contextAn object with vars, test, prompt and provider
ReturnsA boolean, or {pass, score, reason}

Python or JavaScript

Reach forWhen
pythonYour checks or libraries are in Python
javascriptYou want Node, an npm library, or logic that is already JavaScript

Where a JavaScript assertion fits

  • A Node codebase, where the check sits next to the app it tests in the same language.
  • An npm library you want to call from inside the check, such as a date or schema helper.
  • A quick inline rule, where the logic is a line or two of JavaScript on the answer.
Watch out. The function is the module's export, not a named get_assert; that name is the Python convention. In JavaScript, export the function itself, or promptfoo has nothing to call.
Try it yourself
  • Return a plain true from the function and confirm the test passes with no reason.
  • Read context.vars.question and put the question into the reason string.
  • Add a month the bot never says to the list and confirm the passing answer is unchanged.

This is what real progress feels like.