Using these tools with n8n-as-code
n8n-as-code keeps n8n workflows as TypeScript files, *.workflow.ts. These tools read n8n workflow JSON. n8n-as-code converts between the two, offline, so the tools work on an n8n-as-code repository with one extra step: convert, then run.
Note
This page is the supported route for now. Closer support for n8n-as-code is planned.
Tested with n8nac 2.7.0.
Convert the workflows to JSON
Convert every *.workflow.ts file into a build/ folder, subfolders included:
find workflows -name '*.workflow.ts' | while IFS= read -r f; do
out="build/${f%.workflow.ts}.json"
mkdir -p "$(dirname "$out")"
npx n8nac convert "$f" --format json -o "$out" --force
done
This creates:
build/
└── workflows/
├── order-sync.json
└── prod/
└── billing/
└── order-alert.json
Add build/ to .gitignore. The TypeScript files stay the source of truth.
n8nac convert-batch workflows --format json does the same for a single folder. It writes each JSON file next to its .workflow.ts file and does not go into subfolders.
Run the tools
Lint every workflow:
npx workflow-lint lint build
Draw one as an image, for a pull request or a README:
npx workflow-render export build/workflows/order-sync.json -o order-sync.png
Run your payload tests. Point each test file's workflow: at the converted JSON:
npx workflow-tester run
integration-mock needs no conversion. It answers the HTTP calls n8n makes, whatever format the workflow is stored in.
What survives the conversion
A workflow converted to TypeScript and back keeps:
- Node names, types and
typeVersion - Node parameters, expressions included
- Node positions on the canvas
- Connections
- Workflow settings, such as the error workflow
What to know
- Line numbers in workflow-lint's findings point into the converted JSON, not into the
.workflow.tsfile. Use the node name in each finding to find the node in your TypeScript. - Do not use
--fixorfmton the converted files. They would change the JSON inbuild/, which is thrown away. Make the change in the.workflow.tsfile instead. - workflow-tester contracts are written next to the workflow JSON, so
contracts addputs them inbuild/. Keep hand-written tests in.workflow-tester/tests/, which is outsidebuild/.
In GitHub Actions
name: workflows
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- name: Convert to JSON
run: |
find workflows -name '*.workflow.ts' | while IFS= read -r f; do
out="build/${f%.workflow.ts}.json"
mkdir -p "$(dirname "$out")"
npx --yes n8nac convert "$f" --format json -o "$out" --force
done
- run: npx --yes workflow-lint lint build --format github-actions