Free & open source — no account required

v1.2.5-PRICING-19
Web & Frontend • Engineering Documentation

JSON to Yaml Converter

This technical guide provides an in-depth analysis of the json to yaml engine, best practices for implementation, and data security standards.

JSON to YAML: js-yaml Options, Anchors and Aliases, Kubernetes ConfigMaps, and GitHub Actions

YAML is a superset of JSON, but "idiomatic" YAML is more than JSON with brackets removed — it uses features JSON lacks: anchors and aliases (& / *) to reuse blocks without duplication, block scalars (| and >) for multi-line strings, and comments to document configuration intent. Real-world YAML targets — Kubernetes manifests, GitHub Actions workflows, Docker Compose, Helm values — each have style conventions worth following. This guide covers js-yaml's conversion options, the DRY anchor/alias pattern, multi-line scalar styles, and practical examples generating Kubernetes and CI/CD config from JSON data.

Live Example: js-yaml dump() Configuration

import yaml from 'js-yaml';

const config = {
  name: "production-cluster",
  version: "1.2.0",
  database: {
    host:     "db.internal",
    port:     5432,
    name:     "appdb",
    ssl:      true,
    poolSize: 20,
  },
  servers: [
    { id: "node-1", role: "primary",  region: "us-east-1" },
    { id: "node-2", role: "replica",  region: "us-east-1" },
    { id: "node-3", role: "replica",  region: "eu-west-1" },
  ],
  features: {
    logging:    true,
    monitoring: true,
    debug:      false,
  },
};

// Default dump — works fine for most uses
console.log(yaml.dump(config));

// Production options:
console.log(yaml.dump(config, {
  indent:    2,          // indentation spaces (default: 2)
  lineWidth: 120,        // max line width before wrapping long strings (-1 = no limit)
  noRefs:    true,       // don't use & anchors for repeated objects (default: false)
  sortKeys:  false,      // preserve insertion order (true for deterministic output)
  forceQuotes: false,    // only quote strings when necessary
  quotingType: "'",      // use single quotes when quoting is needed
}));

// Output:
// name: production-cluster
// version: 1.2.0
// database:
//   host: db.internal
//   port: 5432
//   name: appdb
//   ssl: true
//   poolSize: 20
// servers:
//   - id: node-1
//     role: primary
//     region: us-east-1
//   - id: node-2
//     role: replica
//     region: us-east-1
//   - id: node-3
//     role: replica
//     region: eu-west-1
// features:
//   logging: true
//   monitoring: true
//   debug: false

Anchors and Aliases: DRY Configuration

// YAML anchors (&name) define a reusable block
// YAML aliases (*name) reference the defined block
// Great for shared environment config, common CI steps, default values

# Without anchors (repetitive)
staging:
  db_host: db-staging.internal
  db_port: 5432
  ssl: true
  pool_size: 10

production:
  db_host: db-prod.internal
  db_port: 5432
  ssl: true
  pool_size: 50

---

# With anchors (DRY)
.db_defaults: &db_defaults
  db_port: 5432
  ssl: true

staging:
  <<: *db_defaults        # merge key — copies db_port and ssl
  db_host: db-staging.internal
  pool_size: 10

production:
  <<: *db_defaults
  db_host: db-prod.internal
  pool_size: 50

// Generating YAML with anchors from JSON using js-yaml:
// js-yaml automatically uses & and * when the SAME object reference appears twice
const dbDefaults = { port: 5432, ssl: true };

const config = {
  staging:    { ...dbDefaults, host: "db-staging.internal", poolSize: 10 },
  production: { ...dbDefaults, host: "db-prod.internal",    poolSize: 50 },
};

// Spread creates NEW objects — no shared references → no anchors in output
// To force anchors, use the SAME reference:
const sharedPool = { port: 5432, ssl: true };
const configWithRefs = {
  staging:    { db: sharedPool, host: "db-staging.internal" },
  production: { db: sharedPool, host: "db-prod.internal" },
};
console.log(yaml.dump(configWithRefs));
// staging:
//   db: &ref_1
//     port: 5432
//     ssl: true
//   host: db-staging.internal
// production:
//   db: *ref_1         <-- alias references the shared object
//   host: db-prod.internal

Multi-line Scalar Styles

// Block scalar styles for long strings — critical for scripts in CI/CD config
// | (literal block) — preserves newlines exactly
// > (folded block) — folds newlines to spaces (single paragraph)

# Kubernetes job with inline script using literal block scalar
apiVersion: batch/v1
kind: Job
spec:
  template:
    spec:
      containers:
      - name: migrator
        command: ["/bin/sh", "-c"]
        args:
          - |
            set -e
            echo "Running database migration..."
            psql $DATABASE_URL -f /migrations/001_add_users.sql
            psql $DATABASE_URL -f /migrations/002_add_indexes.sql
            echo "Migration complete"

# Long description using folded block scalar (newlines become spaces)
description: >
  This job runs database migrations on deployment.
  It connects to the primary database and applies
  all pending migration files in order.

// Generating block scalars with js-yaml from multiline strings:
const manifest = {
  command: ["/bin/sh", "-c"],
  script: "set -e\necho 'Starting...'\nnpm run migrate\necho 'Done'",
  description: "Runs database migrations.\nConnects to primary DB.",
};

// js-yaml automatically uses block style for strings containing newlines
console.log(yaml.dump(manifest, { lineWidth: -1 }));
// command:
//   - /bin/sh
//   - -c
// script: |             <-- literal block, preserves \n
//   set -e
//   echo 'Starting...'
//   npm run migrate
//   echo 'Done'
// description: |
//   Runs database migrations.
//   Connects to primary DB.

Kubernetes ConfigMap from JSON

// Generate a Kubernetes ConfigMap manifest from application config JSON
import yaml from 'js-yaml';

interface AppConfig {
  [key: string]: string | number | boolean | object;
}

function toConfigMap(name: string, namespace: string, config: AppConfig): string {
  const configData: Record<string, string> = {};

  for (const [key, value] of Object.entries(config)) {
    // Kubernetes ConfigMap values are always strings
    configData[key] = typeof value === 'object'
      ? JSON.stringify(value)
      : String(value);
  }

  const manifest = {
    apiVersion: 'v1',
    kind:       'ConfigMap',
    metadata: {
      name,
      namespace,
      labels: { 'managed-by': 'typemorph' },
    },
    data: configData,
  };

  return yaml.dump(manifest, { lineWidth: 120, noRefs: true });
}

const appConfig = {
  LOG_LEVEL:    'info',
  MAX_RETRIES:  3,
  FEATURE_FLAG: true,
  DB_POOL_SIZE: 20,
  CORS_ORIGINS: '["https://app.example.com", "https://api.example.com"]',
};

console.log(toConfigMap('app-config', 'production', appConfig));
// apiVersion: v1
// kind: ConfigMap
// metadata:
//   name: app-config
//   namespace: production
//   labels:
//     managed-by: typemorph
// data:
//   LOG_LEVEL: info
//   MAX_RETRIES: '3'
//   FEATURE_FLAG: 'true'
//   DB_POOL_SIZE: '20'
//   CORS_ORIGINS: '["https://app.example.com", "https://api.example.com"]'

GitHub Actions Workflow from JSON Config

// Generate GitHub Actions workflow YAML from a JSON pipeline definition
const pipeline = {
  name: "CI",
  on: { push: { branches: ["main", "develop"] }, pull_request: null },
  jobs: {
    test: {
      "runs-on": "ubuntu-latest",
      steps: [
        { uses: "actions/checkout@v4" },
        { uses: "actions/setup-node@v4", with: { "node-version": "20", cache: "npm" } },
        { run: "npm ci" },
        { run: "npm run lint" },
        { run: "npm test", env: { CI: "true", DATABASE_URL: "${{ secrets.TEST_DB_URL }}" } },
      ],
    },
    build: {
      "runs-on": "ubuntu-latest",
      needs: "test",
      steps: [
        { uses: "actions/checkout@v4" },
        { uses: "actions/setup-node@v4", with: { "node-version": "20", cache: "npm" } },
        { run: "npm ci" },
        { run: "npm run build" },
        { uses: "actions/upload-artifact@v4", with: { name: "build", path: "dist/" } },
      ],
    },
  },
};

const workflow = yaml.dump(pipeline, {
  lineWidth: -1,   // don't wrap — GitHub Actions is whitespace-sensitive
  noRefs:    true,
  sortKeys:  false,
});
console.log(workflow);
// Write to .github/workflows/ci.yml

Best Practices for Production

  • Use lineWidth: -1 for configuration files that will be parsed by other tools: Automatic line wrapping in long strings can break YAML tools that don't handle continuation correctly. GitHub Actions and Kubernetes are sensitive to this — a line-wrapped command string produces two separate arguments instead of one.
  • Lint converted YAML before deploying: yamllint catches invisible whitespace errors, tab characters (forbidden in YAML), and anchor/alias cycles. Run it in CI on all generated YAML files: yamllint .github/workflows/*.yml k8s/*.yaml.
  • Prefer sortKeys: false to preserve semantic ordering: Kubernetes manifests expect apiVersion before kind before metadata before spec. Alphabetic sorting breaks this convention and makes diffs harder to read. Only use sortKeys: true when generating config files where key order is truly irrelevant.
  • Quote strings that look like other YAML types: YAML interprets yes, no, on, off as booleans in older spec versions (YAML 1.1). Docker Compose and some Kubernetes tools use YAML 1.1. Quote version strings like "1.2" to prevent them being parsed as floats, and quote anything that could be mistaken for a boolean.

FAQ

Q: What's the difference between YAML 1.1 and YAML 1.2, and which one should I use?
A: YAML 1.1 (used by most legacy tools including older PyYAML and Ruby's Psych) treats yes/no/on/off as booleans and parses unquoted floats like 1_000 with underscores. YAML 1.2 (stricter, JSON-compatible) only recognizes true/false as booleans. js-yaml defaults to YAML 1.2 behavior for output, which is safer. Always quote values that could be misinterpreted by a YAML 1.1 parser.

Q: How do I add comments to YAML generated from JSON?
A: JSON has no comment syntax, so comment information isn't in the source. Add comments by post-processing the YAML string or by using a template approach where you maintain a YAML template with comments and merge JSON values into it. The yaml package (not js-yaml) supports round-trip parsing that preserves comments if you start from a commented YAML file.

Q: Can YAML handle binary data like images?
A: Yes, YAML supports binary data with the !!binary tag, encoded as Base64. This is rarely used in practice — for configuration files, reference binary assets by path or URL rather than embedding them inline. Kubernetes Secrets use Base64-encoded values in YAML, but those are just string values, not YAML !!binary nodes.

Developer FAQ

Is the processing local-only?

Absolutely. TypeMorph operates entirely within your browser's sandbox. We use Web Workers for high-performance computation without ever transmitting your JSON, SQL, or API data to a remote server.

Can I use this for enterprise projects?

Yes. The tool is designed for professional software engineers who require GDPR compliance and data privacy. It is trusted by developers at top-tier startups and financial institutions.