Developer Tools

Pretty JSON

Format selected JSON with readable indentation.

OfficialOn-device

Download action

What Pretty JSON does

Validates JSON and formats it with two-space indentation without rewriting large numeric literals or duplicate keys.

CategoryDeveloper Tools
Action typeJavaScript
ResultReplace or copy text
InternetNot required

Action and outcome

Pretty JSON example
ActionOutcome
Pretty JSONSelected text: {"name":"ActionClip","enabled":true}{ "name": "ActionClip", "enabled": true }

Use Pretty JSON

Follow these steps to format selected JSON with readable indentation with ActionClip.

  1. Select the text you want to use.
  2. Choose Pretty JSON from ActionClip.
  3. Review the result, then replace the selection or copy the new text.

Requirements and privacy

  • Before you start: No setup required.
  • Your selected text: Runs locally in ActionClip’s JavaScript sandbox. Selected text does not leave your Mac.

Action configuration

The definition below is included so you can inspect how the action works before downloading it.

JavaScript definition
function run(selected_text) {
  const input = selected_text.trim();
  try {
    JSON.parse(input);
  } catch (error) {
    throw new Error("Invalid JSON: " + error.message);
  }

  let output = "";
  let depth = 0;
  let inString = false;
  let escaped = false;
  const indent = () => "  ".repeat(depth);
  const nextNonWhitespace = (start) => {
    for (let index = start; index < input.length; index += 1) {
      if (!/\s/.test(input[index])) return input[index];
    }
    return "";
  };

  for (let index = 0; index < input.length; index += 1) {
    const character = input[index];
    if (inString) {
      output += character;
      if (escaped) escaped = false;
      else if (character === "\\") escaped = true;
      else if (character === '"') inString = false;
      continue;
    }

    if (character === '"') {
      inString = true;
      output += character;
    } else if (character === "{" || character === "[") {
      output += character;
      const closing = character === "{" ? "}" : "]";
      if (nextNonWhitespace(index + 1) !== closing) {
        depth += 1;
        output += "\n" + indent();
      }
    } else if (character === "}" || character === "]") {
      const opening = character === "}" ? "{" : "[";
      let previous = output.length - 1;
      while (previous >= 0 && /\s/.test(output[previous])) previous -= 1;
      if (previous >= 0 && output[previous] !== opening) {
        depth = Math.max(0, depth - 1);
        output = output.replace(/\s+$/, "") + "\n" + indent();
      }
      output += character;
    } else if (character === ",") {
      output += ",\n" + indent();
    } else if (character === ":") {
      output += ": ";
    } else if (!/\s/.test(character)) {
      output += character;
    }
  }
  return output;
}