Convert JSON to GitHub Actions YAML Workflow
- Paste a JSON workflow definition, click Convert, get YAML that drops into .github/workflows/.
- Handy for CI generators, matrix builders, or teams migrating from other CI platforms.
- Works for standard workflows, reusable workflows, and composite actions.
Table of Contents
GitHub Actions workflows live under .github/workflows/ as YAML files. If you're generating workflows programmatically — a custom CI generator, a tool that migrates from Jenkins or CircleCI, or a dynamic matrix builder — you'll often have a JSON representation of the workflow first. A browser converter flips it to YAML in one paste. This guide covers standard workflows, matrix configs, and reusable workflow inputs.
A Standard Workflow Conversion
Input:
{"name":"CI","on":["push","pull_request"],"jobs":{"test":{"runs-on":"ubuntu-latest","steps":[{"uses":"actions/checkout@v4"},{"uses":"actions/setup-node@v4","with":{"node-version":"20"}},{"run":"npm ci"},{"run":"npm test"}]}}}
Paste into the converter. Output:
name: CI
on:
- push
- pull_request
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npm ci
- run: npm test
Save under .github/workflows/ci.yaml. Push. GitHub picks it up automatically.
Matrix Builds — Where JSON Generation Shines
Dynamic matrix generation is a common pattern: a preceding job outputs a JSON matrix, a downstream job consumes it.
If you're authoring the matrix config by hand or generating it offline, JSON is easier to produce programmatically. Convert to YAML once you finalize the shape.
# Generated JSON
{"include":[{"os":"ubuntu-latest","node":"18"},{"os":"ubuntu-latest","node":"20"},{"os":"macos-latest","node":"20"}]}
Converted YAML:
include:
- os: ubuntu-latest
node: "18"
- os: ubuntu-latest
node: "20"
- os: macos-latest
node: "20"
Drop under strategy.matrix in your workflow.
Reusable Workflows and Composite Actions
Reusable workflows (workflow_call) and composite actions both have inputs and outputs declared in YAML. If you have a JSON spec of what the workflow accepts, converting to YAML gives you the starting skeleton.
{"name":"Deploy","on":{"workflow_call":{"inputs":{"environment":{"type":"string","required":true},"version":{"type":"string","default":"latest"}}}}}
Becomes:
name: Deploy
on:
workflow_call:
inputs:
environment:
type: string
required: true
version:
type: string
default: latest
Gotchas With GitHub Actions YAML
- String vs bool. GitHub expects strings for version numbers:
node-version: "20"notnode-version: 20. Make sure your source JSON has quoted strings. - Boolean "on". YAML 1.1 interpreted
onas true. YAML 1.2 (which GitHub uses) treats it correctly. Still, when writing YAML by hand, people quote it. Our converter preserves the source JSON, so"on": ["push"]becomeson:unquoted. Works fine on GitHub. - Expressions like [object Object]. GitHub expressions pass through unchanged. Keep them as strings in the source JSON.
- Multi-line run blocks. Long scripts are clearer as
run: |block scalars in YAML. Our converter doesn't auto-promote — if your JSON has\n, the output has\n. Hand-edit to|for readability.
Validate Before Pushing
GitHub validates workflows only when a push triggers them. Validate locally first:
- act — run GitHub Actions locally in Docker.
act pushsimulates the push trigger. - actionlint — static checker for workflow files. Catches most errors before push.
Both work on YAML. Convert, then validate, then push.
Generate Workflows Once, Commit as YAML
Paste JSON, click Convert, save under .github/workflows/. Ready on next push.
Open Free JSON to YAML ConverterFrequently Asked Questions
Can GitHub Actions read JSON workflow files directly?
No. GitHub requires .yaml or .yml extension for workflow files. Converting JSON to YAML is a hard requirement if your pipeline is generating JSON.
What about reading JSON inside a workflow step?
Steps can parse JSON using fromJSON() in expressions or jq in a run block. That's different from the workflow file format itself, which must be YAML.
Why does my converted workflow fail with "invalid yaml" on GitHub?
Usually one of three issues: an unquoted "on" keyword (rare), a version number passed as a number instead of string, or an expression like ${{ secrets.X }} that got double-escaped. Paste the YAML into actionlint before pushing.
Can I convert a CircleCI JSON config to GitHub Actions YAML?
Not directly — the structure differs. Converting the JSON to YAML gives you readable YAML but in CircleCI format. You'd then need to translate that to GitHub Actions syntax. Tools like action-migration exist, but none are one-click.

