---
title: "Custom JS Integration"
description: "CustomJS bundles PDF generation, screenshots, web scraping, hosted pages, and server-side JavaScript behind one API key. Workflows convert HTML or Markdown to PDF, merge and compress PDFs, scrape or screenshot pages, run stored functions, and publish hosted pages."
url: https://flowrunner.ai/integrations/custom-js
date_modified: 2026-09-04T14:59:52-07:00
---

# Custom JS

[Developer Tools](https://flowrunner.ai/integrations/category/developer-infrastructure)

CustomJS bundles PDF generation, screenshots, web scraping, hosted pages, and server-side JavaScript behind one API key. Workflows convert HTML or Markdown to PDF, merge and compress PDFs, scrape or screenshot pages, run stored functions, and publish hosted pages.

[Verified](https://flowrunner.ai/integrations/verified "What does verified mean?") · 17 actions · API key · available

[Custom JS website](https://customjs.space/) · [Platform Documentation](https://www.customjs.space/) · Capability data verified 2026-08-25

1.  A billing run closes and each account's statement data is ready
2.  Agent assembles the line items, totals, and account details for one statement
3.  HTML To PDF renders the stored layout with that account's data merged in
4.  Agent confirms every referenced logo and stylesheet resolved, because a missing asset does not fail the render, it simply is not in the PDF
5.  Merge PDFs appends the standing terms document to each statement
6.  The finished statement links post to the account owners
7.  A person reads the first statement of any changed layout, since a document built from partly-loaded assets is still a valid document

## What This Integration Enables

Every automation program eventually meets the same wall. The process is ninety percent covered by real [connectors](https://flowrunner.ai/concepts/connectors), and then there is one step that is nobody's product:

-   turn this markup into a PDF
-   take a picture of that page, after dismissing the cookie banner
-   pull the numbers out of a supplier portal with no API
-   run this one piece of transformation logic

Teams usually solve each of those separately, and end up with four vendors, four keys, and four bills for what is really one category of problem.

CustomJS covers that category behind a single key. FlowRunner agents render HTML or Markdown into PDFs and then merge, compress, split, and read them. They capture screenshots of pages that need clicking through first, read pages three different ways at three different costs, execute server-side JavaScript with a substantial standard library available, and publish HTML at a stable public URL. The reason this belongs in a FlowRunner flow rather than in a script is that an escape hatch is a governance question, not just a convenience. Three of these operations spend real money per step, one of them can be handed a login, and one of them runs code that changes in a vendor's editor rather than in your flow. FlowRunner's [human-in-the-loop](https://flowrunner.ai/concepts/human-in-the-loop) discipline is what keeps those three from being the quiet part of your automation.

### Without FlowRunner

**The gap nobody owns**: Every process has one step that no connector covers, and that step is where the automation stops

**A service per gap**: Filling those steps means separate accounts, keys, and bills for PDFs, screenshots, scraping, and hosting

**Logic pasted into every flow**: The same twenty lines of transformation live in six different places and diverge the first time one is fixed

### With FlowRunner

**The gaps are covered**: Document generation, capture, page reading, code execution, and hosted output run behind one key

**Logic stored once**: A stored function is versioned in one place and every flow sends it data rather than a copy of the code

**Escape hatches with a gate**: The operations that spend money or hold credentials pause for a person instead of running on trust

## Use Case Scenarios

### Statements and certificates produced from data, not from a designer

A billing run closes in [Stripe](https://flowrunner.ai/integrations/stripe) and the agent builds each account's statement. HTML To PDF accepts Nunjucks template data, so one stored layout produces every account's document rather than the flow concatenating markup by hand. Merge PDFs appends the standing terms, Compress PDF brings the file under the mailbox limit for accounts that need it posted rather than linked, and the finished documents land in [Google Drive](https://flowrunner.ai/integrations/google-drive-api) with links posted to the owners in [Slack](https://flowrunner.ai/integrations/slack). The same pattern produces certificates, contracts, and onboarding packets, and none of them go through a design queue.

### Evidence captured at the moment it mattered

A monitoring alert fires, or a competitor changes a price, or a compliance check needs proof that a disclosure was on the page today. Take Screenshot loads the page in a real browser, and its Commands run before the capture, which is what makes it usable on a production site: dismiss the consent dialog, sign in, wait for the chart to draw, then shoot. Without that step most screenshots of real sites are pictures of a cookie banner. The capture attaches to the record in [Airtable](https://flowrunner.ai/integrations/airtable) with a timestamp, and the agent moves on.

### A live dashboard that is a URL, not a report

An operations team wants a page they can open rather than a message they have to search for. On a schedule, the agent gathers the day's numbers, renders them into HTML, and calls Publish Hosted Page. That operation matters more than it sounds: Create Hosted Page fails on a duplicate name, Update Hosted Page needs an id the first run does not have, and Publish does the match-then-create-or-update work in one call. The live URL does not change on update, so the link the team bookmarked in January still shows today's numbers.

## Human-in-Loop Highlight

AI Scrape is the operation on this connector that stops being a data question and becomes a permissions question. It drives a real browser toward a plain-language goal, it costs AI tokens per browser action, and it accepts a Credentials object which the agent uses to fill in matching login fields by itself. That is genuinely useful, and it means a model is typing your username and password into a third-party site, taking steps you did not enumerate, against a page that may have changed since anyone looked at it. Max Steps is the only ceiling on the bill, and the vendor's own guidance is to use a dedicated low-privilege account.

So the agent never assembles that call unattended. It prepares the request and asks the operations owner who authorized the target: "The supplier portal scrape needs a signed-in session. This would send the `automation@` service account credentials to CustomJS, which types them into portal.example.com, with a goal of 'download the current price list' and a ceiling of 25 steps. Last run reported 0.42 US dollars at 18 steps. Approve this target and step budget, or should I use Automate Browser with a scripted sequence instead?" Automate Browser is often the right answer once the page is understood, because it costs nothing per step and its extractions are keyed and repeatable. What the gate protects is not the money. It is that nobody hands out a credential by accident.

Agent processes routinely

Detects exception requiring judgment

Clear match Continues automatically

Ambiguous Routes to human via preferred channel

Human decides

Agent resumes with decision

## Agent Capabilities

17 actions

### Documents

7

-   **HTML To PDF** Renders HTML in a real browser and stores the resulting PDF. CSS, web fonts, and JavaScript all run first, and Nunjucks template data means one stored layout produces a different document each run.
-   **Markdown To PDF** Renders Markdown as a PDF. Shorter than hand-writing HTML when the document is prose: a report, a summary, or a generated write-up goes straight in.
-   **Merge PDFs** Combines several PDFs into one, in the order given. It takes URLs rather than file content, and CustomJS fetches each one anonymously, so a document behind a login is unreachable.
-   **Compress PDF** Shrinks a PDF. It is lossy on images, so a scan or a photo-heavy brochure loses quality where a text document does not.
-   **PDF To PNG** Renders a PDF's pages as images. The way to show a document preview, or to hand a page to a model that cannot read PDFs.
-   **PDF To Text** Extracts a PDF's text. It reads the text layer and does not perform character recognition, so a scanned document returns an empty string and still succeeds. Check for empty rather than assuming the page was blank.
-   **Extract PDF Pages** Pulls selected pages into a new document. Worth testing the page indexing on a throwaway file first, because an off-by-one produces a perfectly valid PDF of the wrong pages and nothing downstream can tell.

### Capture and page reading

4

-   **Take Screenshot** Loads a page in a real browser and stores a PNG. Commands run before the capture, so a flow can dismiss a banner, sign in, or wait for content to draw before shooting.
-   **Scrape Page** Fetches a page's HTML. The cheapest of the three reading options: no model, no scripted steps, just the markup. Reach for the other two only when this is not enough.
-   **Automate Browser** Runs an exact sequence of browser steps and returns what they extracted. No per-step model cost, and the results are keyed and repeatable, which is what a scheduled read of a page you already understand should use.
-   **AI Scrape** Gives a plain-language goal to an agent that drives a real browser. It costs tokens per step and reports the estimated spend, its output is the model's own prose summary rather than structured fields, and it can be given credentials to sign in. The operation this page's human gate exists for.

### Running code

2

-   **Run JavaScript** Executes JavaScript on CustomJS servers with your input and returns the result. The escape hatch for everything else, with a substantial library set available to the script.
-   **Run Stored Function** Calls a script saved in the CustomJS editor by its id. The right shape for production, because the logic is versioned in one place instead of pasted into every flow. Note that updates then happen in the vendor's editor, so behavior can change with no deployment on your side.

### Hosted pages

4

-   **List Hosted Pages** Returns the HTML pages hosted in your workspace. The only way to find a page's id, and the list has no filter, so names have to be stable.
-   **Create Hosted Page** Publishes an HTML document and returns its live URL. Fails when the name already exists in the workspace.
-   **Update Hosted Page** Replaces a hosted page's HTML in place. The live URL does not change, which is what makes a published link usable as a permanent dashboard.
-   **Publish Hosted Page** Creates a page if its name is new and replaces its HTML if it already exists. The operation a scheduled flow should use, because it does not need an id on the first run and does not fail on the second.

## Frequently Asked Questions

### What can FlowRunner do with Custom JS?

FlowRunner agents can run HTML To PDF, Markdown To PDF, and Merge PDFs in Custom JS, plus 14 more actions.

### Does connecting Custom JS to FlowRunner require OAuth?

No. Custom JS connects to FlowRunner with an API key, no OAuth flow required.

### Can Custom JS trigger a FlowRunner workflow automatically?

Custom JS doesn't currently expose triggers in FlowRunner. It connects as an action step inside workflows started by another trigger.

**Work at Custom JS?** This integration exposes Custom JS to AI agents on every FlowRunner plan, including through MCP, at no cost to you. [See what FlowRunner offers integration partners](https://flowrunner.ai/integrations/partners), including how to keep this page current.

---
Markdown version of https://flowrunner.ai/integrations/custom-js. Site index: https://flowrunner.ai/llms.txt
