prettier programmatic formatting API: working versions (tested 2026-10-15)
Format TypeScript, JSON and Markdown strings with prettier 3's async format/check APIs, applying semi=false, singleQuote and printWidth, and proving idempotence.
passed5 passed · 0 failed2026-10-15 22:58 UTC- Status
- passed
- Last passed
- 2026-10-15 22:58 UTC
- Tests
- 5 / 5
- Language
- TypeScript
- Runtime
- node v22.23.3
pinned versions3
prettier@3.9.10@types/node@26.6.5tsx@4.23.15
run it
npm install --no-audit --no-fund --ignore-scripts=false npm test
test environment
node v22.23.3 linux 6.17.0-1022-azure x64 runner: github-actions 38820570375
The code
Exactly the files that passed. Your agent can pull them with get_recipe("prettier-format-api") (install), or see them on GitHub.
package.json
{
"name": "prettier-format-api",
"private": true,
"type": "module",
"scripts": {
"test": "node --import tsx --test test/*.test.ts"
},
"dependencies": {
"prettier": "3.9.10"
},
"devDependencies": {
"@types/node": "26.6.5",
"tsx": "4.23.15"
}
}
src/formatter.ts
import { check, format, type Options } from "prettier";
export const baseOptions = {
semi: false,
singleQuote: true,
} satisfies Options;
export type FormatParser = "typescript" | "json" | "markdown";
export function formatSource(
source: string,
parser: FormatParser,
options: Options = {},
): Promise<string> {
return format(source, { ...baseOptions, parser, ...options });
}
export function checkSource(
source: string,
parser: FormatParser,
options: Options = {},
): Promise<boolean> {
return check(source, { ...baseOptions, parser, ...options });
}
export function formatTypeScript(
source: string,
options: Options = {},
): Promise<string> {
return formatSource(source, "typescript", options);
}
export function formatJson(
source: string,
options: Options = {},
): Promise<string> {
return formatSource(source, "json", options);
}
export function formatMarkdown(
source: string,
options: Options = {},
): Promise<string> {
return formatSource(source, "markdown", options);
}
test/formatter.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import {
checkSource,
formatJson,
formatMarkdown,
formatTypeScript,
} from "../src/formatter.ts";
test("formats TypeScript with single quotes and no semicolons", async () => {
const source =
'const greeting: string = "hello";\nexport function greet(name: string): string {\n return `${greeting}, ${name}`;\n}\n';
const out = await formatTypeScript(source);
assert.match(out, /'hello'/);
assert.ok(!out.includes(";"));
assert.equal(
out,
"const greeting: string = 'hello'\nexport function greet(name: string): string {\n return `${greeting}, ${name}`\n}\n",
);
});
test("respects printWidth for TypeScript", async () => {
const source =
'const message = ["alpha", "beta", "gamma", "delta", "epsilon"].join(", ");\n';
const out = await formatTypeScript(source, { printWidth: 40 });
assert.ok(out.split("\n").length > 1);
assert.ok(!out.includes(";"));
});
test("is idempotent for TypeScript, JSON and Markdown", async () => {
const tsRaw = 'const x = { a: 1, b: 2 };\n';
const jsonRaw = '{"a":1,"b":[1,2,3]}';
const mdRaw = "# Title\n\nParagraph.\n";
const tsOnce = await formatTypeScript(tsRaw);
const jsonOnce = await formatJson(jsonRaw);
const mdOnce = await formatMarkdown(mdRaw);
assert.equal(await formatTypeScript(tsOnce), tsOnce);
assert.equal(await formatJson(jsonOnce), jsonOnce);
assert.equal(await formatMarkdown(mdOnce), mdOnce);
});
test("check returns true on formatted output and false otherwise", async () => {
const tsRaw = 'const x = "a";\n';
const tsFormatted = await formatTypeScript(tsRaw);
assert.equal(await checkSource(tsFormatted, "typescript"), true);
assert.equal(await checkSource(tsRaw, "typescript"), false);
const jsonRaw = '{"a":1}';
const jsonFormatted = await formatJson(jsonRaw);
assert.equal(await checkSource(jsonFormatted, "json"), true);
assert.equal(await checkSource(jsonRaw, "json"), false);
const mdRaw = "# Title\n";
const mdFormatted = await formatMarkdown(mdRaw);
assert.equal(await checkSource(mdFormatted, "markdown"), true);
assert.equal(await checkSource(mdRaw, "markdown"), false);
});
test("formats JSON and Markdown predictably", async () => {
const json = await formatJson('{"a":1,"b":[1,2,3]}');
assert.deepEqual(JSON.parse(json), { a: 1, b: [1, 2, 3] });
assert.ok(json.includes("\n"));
const md = await formatMarkdown("# Title\n\nParagraph.\n");
assert.equal(md, "# Title\n\nParagraph.\n");
});
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
~/.cursor/mcp.json
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }.vscode/mcp.json
{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }MCP settings
{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.