├── .node-version ├── .prettierrc.json ├── .gitignore ├── .github ├── renovate.json └── workflows │ └── ci.yml ├── .oxfmtrc.json ├── package.json ├── biome.json ├── setup.sh ├── scripts └── update-readme-bench.js ├── README.md ├── benchmark.mjs └── pnpm-lock.yaml /.node-version: -------------------------------------------------------------------------------- 1 | lts/* 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | outline/ 4 | parser.ts 5 | parser.ts.bak 6 | hyperfine-*/ 7 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["github>Boshen/renovate"] 4 | } 5 | -------------------------------------------------------------------------------- /.oxfmtrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "useTabs": true, 4 | "ignorePatterns": [ 5 | "**/*.css", 6 | "**/*.html", 7 | "**/*.md", 8 | "**/*.yml", 9 | "**/*.json", 10 | "!parser.ts", 11 | "!outline" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bench-formatter", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "packageManager": "pnpm@10.25.0", 6 | "description": "Benchmark suite for JS/TS formatters", 7 | "devDependencies": { 8 | "@biomejs/biome": "^2.3.8", 9 | "@prettier/plugin-oxc": "^0.1.2", 10 | "oxfmt": "^0.19.0", 11 | "prettier": "^3.7.3" 12 | }, 13 | "scripts": { 14 | "setup": "./setup.sh", 15 | "bench": "node benchmark.mjs", 16 | "bench:update-readme": "node scripts/update-readme-bench.js" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", 3 | "vcs": { 4 | "useIgnoreFile": false 5 | }, 6 | "formatter": { 7 | "includes": [ 8 | "outline/**/*.js", 9 | "outline/**/*.jsx", 10 | "outline/**/*.ts", 11 | "outline/**/*.tsx", 12 | "parser.ts" 13 | ], 14 | "formatWithErrors": true 15 | }, 16 | "linter": { 17 | "enabled": false 18 | }, 19 | "json": { 20 | "formatter": { 21 | "enabled": false 22 | } 23 | }, 24 | "css": { 25 | "formatter": { 26 | "enabled": false 27 | } 28 | }, 29 | "graphql": { 30 | "formatter": { 31 | "enabled": false 32 | } 33 | }, 34 | "grit": { 35 | "formatter": { 36 | "enabled": false 37 | } 38 | }, 39 | "html": { 40 | "formatter": { 41 | "enabled": false 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: [opened, synchronize] 7 | push: 8 | branches: 9 | - main 10 | 11 | permissions: {} 12 | 13 | concurrency: 14 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} 15 | cancel-in-progress: ${{ github.ref_name != 'main' }} 16 | 17 | jobs: 18 | benchmark: 19 | name: Benchmark 20 | runs-on: ubuntu-latest 21 | permissions: 22 | contents: write 23 | steps: 24 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 25 | with: 26 | token: ${{ secrets.OXC_BOT_PAT }} 27 | 28 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 29 | with: 30 | repository: outline/outline 31 | path: outline 32 | 33 | - uses: oxc-project/setup-node@141eb77546de6702f92d320926403fe3f9f6a6f2 # v1.0.5 34 | 35 | - uses: taiki-e/install-action@61e5998d108b2b55a81b9b386c18bd46e4237e4f # v2.63.1 36 | with: 37 | tool: hyperfine 38 | 39 | - run: pnpm run setup 40 | - run: pnpm run bench:update-readme 41 | 42 | - uses: stefanzweifel/git-auto-commit-action@28e16e81777b558cc906c8750092100bbb34c5e3 # v7.0.0 43 | if: github.ref == 'refs/heads/main' && github.event_name == 'push' 44 | with: 45 | commit_message: 'chore: update benchmark results in README [skip ci]' 46 | file_pattern: README.md 47 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Install pnpm dependencies 4 | echo "Installing pnpm dependencies..." 5 | pnpm install 6 | 7 | # Clone Outline repository if not exists 8 | if [ ! -d "outline" ]; then 9 | echo "Cloning Outline repository..." 10 | git clone --depth=1 https://github.com/outline/outline.git 11 | else 12 | echo "Outline repository already exists" 13 | fi 14 | 15 | # Download TypeScript compiler parser.ts if not exists 16 | if [ ! -f "parser.ts" ]; then 17 | echo "Downloading TypeScript compiler parser.ts..." 18 | curl -o parser.ts https://raw.githubusercontent.com/microsoft/TypeScript/refs/tags/v5.9.2/src/compiler/parser.ts 19 | cp parser.ts parser.ts.bak 20 | echo "✓ Downloaded parser.ts (TypeScript v5.9.2)" 21 | else 22 | echo "parser.ts already exists" 23 | fi 24 | 25 | # Check hyperfine installation 26 | if ! command -v hyperfine &> /dev/null; then 27 | echo "" 28 | echo "⚠️ Hyperfine is not installed!" 29 | echo "Please install hyperfine: https://github.com/sharkdp/hyperfine" 30 | echo "On macOS: brew install hyperfine" 31 | echo "On Ubuntu/Debian: apt install hyperfine" 32 | else 33 | echo "✓ Hyperfine is installed" 34 | fi 35 | 36 | # Check GNU time installation 37 | if command -v gtime &> /dev/null; then 38 | echo "✓ GNU time is installed (gtime)" 39 | elif /usr/bin/time --version &> /dev/null; then 40 | echo "✓ GNU time is installed (/usr/bin/time)" 41 | else 42 | echo "" 43 | echo "⚠️ GNU time is not installed!" 44 | echo "Memory benchmarking requires GNU time (not BSD time)" 45 | echo "On macOS: brew install gnu-time (installs as gtime)" 46 | echo "On Ubuntu/Debian: apt install time" 47 | fi 48 | 49 | echo "" 50 | echo "Setup complete! Run 'pnpm run bench' to start benchmarking." 51 | -------------------------------------------------------------------------------- /scripts/update-readme-bench.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { exec } from "child_process"; 4 | import { readFile, writeFile } from "fs/promises"; 5 | import { promisify } from "util"; 6 | 7 | const execAsync = promisify(exec); 8 | 9 | async function runBenchmark() { 10 | console.log("Running benchmark..."); 11 | try { 12 | const { stdout } = await execAsync("pnpm run bench"); 13 | return stdout; 14 | } catch (error) { 15 | console.error("Error running benchmark:", error); 16 | process.exit(1); 17 | } 18 | } 19 | 20 | function extractBenchmarkResults(output) { 21 | // Extract everything from "=========================================" onwards 22 | // This captures both the parser.ts and outline repository benchmarks 23 | const benchmarkStartMatch = output.match( 24 | /=========================================\nBenchmarking .*?\n=========================================\n([\s\S]*)/ 25 | ); 26 | 27 | if (!benchmarkStartMatch) { 28 | throw new Error("Could not find benchmark results in output"); 29 | } 30 | 31 | const benchmarkSection = benchmarkStartMatch[0].trim(); 32 | 33 | return benchmarkSection; 34 | } 35 | 36 | async function getVersions() { 37 | console.log("Fetching versions..."); 38 | try { 39 | const [prettier, biome, oxfmt] = await Promise.all([ 40 | execAsync("pnpm prettier --version"), 41 | execAsync("pnpm biome --version"), 42 | execAsync("pnpm oxfmt --version"), 43 | ]); 44 | 45 | return { 46 | prettier: prettier.stdout.trim(), 47 | biome: biome.stdout.trim().replace("Version: ", ""), 48 | oxfmt: oxfmt.stdout.trim().replace("Version: ", ""), 49 | }; 50 | } catch (error) { 51 | console.error("Error fetching versions:", error); 52 | process.exit(1); 53 | } 54 | } 55 | 56 | async function updateReadme(benchmarkResults, versions) { 57 | console.log("Updating README..."); 58 | 59 | const readmePath = "README.md"; 60 | let readmeContent = await readFile(readmePath, "utf-8"); 61 | 62 | // Find the benchmark results section between markers 63 | const startMarker = ""; 64 | const endMarker = ""; 65 | 66 | const startIndex = readmeContent.indexOf(startMarker); 67 | const endIndex = readmeContent.indexOf(endMarker); 68 | 69 | if (startIndex === -1 || endIndex === -1) { 70 | throw new Error("Could not find benchmark results markers in README.md"); 71 | } 72 | 73 | // Create the new benchmark content 74 | const newBenchmarkContent = `\`\`\` 75 | ${benchmarkResults} 76 | \`\`\``; 77 | 78 | // Replace the content between markers 79 | const beforeMarker = readmeContent.substring( 80 | 0, 81 | startIndex + startMarker.length 82 | ); 83 | const afterMarker = readmeContent.substring(endIndex); 84 | 85 | readmeContent = 86 | beforeMarker + "\n" + newBenchmarkContent + "\n" + afterMarker; 87 | 88 | // Update versions section 89 | const versionsRegex = /## Versions\n\n- \*\*Prettier\*\*: .*\n- \*\*Biome\*\*: .*\n- \*\*Oxfmt\*\*: .*/; 90 | const newVersionsContent = `## Versions\n\n- **Prettier**: ${versions.prettier}\n- **Biome**: ${versions.biome}\n- **Oxfmt**: ${versions.oxfmt}`; 91 | 92 | if (versionsRegex.test(readmeContent)) { 93 | readmeContent = readmeContent.replace(versionsRegex, newVersionsContent); 94 | } else { 95 | console.warn("Could not find versions section in README.md"); 96 | } 97 | 98 | await writeFile(readmePath, readmeContent); 99 | console.log("README updated successfully"); 100 | } 101 | 102 | async function main() { 103 | try { 104 | const benchmarkOutput = await runBenchmark(); 105 | const results = extractBenchmarkResults(benchmarkOutput); 106 | const versions = await getVersions(); 107 | await updateReadme(results, versions); 108 | 109 | console.log("README has been updated with the latest benchmark results"); 110 | } catch (error) { 111 | console.error("Error:", error.message); 112 | process.exit(1); 113 | } 114 | } 115 | 116 | main(); 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript/TypeScript Formatter Benchmark 2 | 3 | Comparing execution time and memory usage of **Prettier**, **Biome**, and **Oxfmt**. 4 | 5 | ## Formatters 6 | 7 | - [Prettier](https://prettier.io/) 8 | - [Prettier](https://prettier.io/) + @prettier/plugin-oxc 9 | - [Biome](https://biomejs.dev/) Formatter 10 | - [Oxfmt](https://oxc.rs) 11 | 12 | ## Versions 13 | 14 | - **Prettier**: 3.7.4 15 | - **Biome**: 2.3.8 16 | - **Oxfmt**: 0.19.0 17 | 18 | ## Setup 19 | 20 | ```bash 21 | # Install dependencies and clone fixtures 22 | pnpm run setup 23 | 24 | # Run the benchmark 25 | pnpm run bench 26 | ``` 27 | 28 | ## Notes 29 | 30 | - Each formatter runs on the exact same codebase state (git reset between runs) 31 | - Times include both parsing and formatting of all matched files 32 | - Memory measurements track peak resident set size (RSS) during execution 33 | - I intended to bench checker.ts, but it appears to be running for a very long time or stuck with 100% CPU. 34 | 35 | ## Benchmark Details 36 | 37 | - **Test Data**: 38 | - [Outline](https://github.com/outline/outline) repository (1925 files, ~198K lines of JS/JSX/TS/TSX code) 39 | - TypeScript compiler's [parser.ts](https://github.com/microsoft/TypeScript/blob/v5.9.2/src/compiler/parser.ts) (~13.7K lines, single large file) 40 | - **Methodology**: 41 | - 3 warmup runs before measurement 42 | - 10 benchmark runs for statistical accuracy 43 | - Git reset before each run to ensure identical starting conditions 44 | - Memory usage measured using GNU time (peak RSS) 45 | - Local binaries via `./node_modules/.bin/` 46 | - prettier: 47 | - `./node_modules/.bin/prettier "$@" --write --experimental-cli --embedded-language-formatting=off --ignore-path=.prettierignore --no-cache --ignore-unknown` 48 | - prettier + oxc plugin: 49 | - `./node_modules/.bin/prettier "$@" --write --experimental-cli --embedded-language-formatting=off --ignore-path=.prettierignore --no-cache --ignore-unknown --plugin @prettier/plugin-oxc` 50 | - biome: 51 | - `./node_modules/.bin/biome format --write --files-ignore-unknown=true "$@"` 52 | - oxfmt: 53 | - `./node_modules/.bin/oxfmt "$@"` 54 | 55 | ## Results 56 | 57 | 58 | ``` 59 | ========================================= 60 | Benchmarking parser.ts (single large file) 61 | ========================================= 62 | Benchmark 1: prettier 63 | Time (mean ± σ): 1.102 s ± 0.013 s [User: 2.200 s, System: 0.237 s] 64 | Range (min … max): 1.087 s … 1.123 s 10 runs 65 | 66 | Benchmark 2: prettier+oxc-parser 67 | Time (mean ± σ): 852.6 ms ± 45.9 ms [User: 1415.0 ms, System: 144.6 ms] 68 | Range (min … max): 788.3 ms … 921.6 ms 10 runs 69 | 70 | Benchmark 3: biome 71 | Time (mean ± σ): 137.8 ms ± 1.7 ms [User: 107.8 ms, System: 28.1 ms] 72 | Range (min … max): 135.2 ms … 140.7 ms 10 runs 73 | 74 | Benchmark 4: oxfmt 75 | Time (mean ± σ): 120.2 ms ± 2.7 ms [User: 243.7 ms, System: 63.2 ms] 76 | Range (min … max): 117.0 ms … 125.0 ms 10 runs 77 | 78 | Summary 79 | oxfmt ran 80 | 1.15 ± 0.03 times faster than biome 81 | 7.09 ± 0.41 times faster than prettier+oxc-parser 82 | 9.17 ± 0.23 times faster than prettier 83 | 84 | Memory Usage: 85 | prettier: 282.4 MB (min: 261.6 MB, max: 320.2 MB) 86 | prettier+oxc-parser: 237.3 MB (min: 232.4 MB, max: 241.0 MB) 87 | biome: 63.4 MB (min: 62.2 MB, max: 66.3 MB) 88 | oxfmt: 161.9 MB (min: 161.7 MB, max: 162.2 MB) 89 | 90 | ========================================= 91 | Benchmarking Outline repository 92 | ========================================= 93 | Benchmark 1: prettier 94 | Time (mean ± σ): 9.657 s ± 0.124 s [User: 31.949 s, System: 3.043 s] 95 | Range (min … max): 9.512 s … 9.878 s 10 runs 96 | 97 | Benchmark 2: prettier+oxc-parser 98 | Time (mean ± σ): 6.987 s ± 0.192 s [User: 20.870 s, System: 2.276 s] 99 | Range (min … max): 6.749 s … 7.421 s 10 runs 100 | 101 | Benchmark 3: biome 102 | Time (mean ± σ): 887.2 ms ± 79.9 ms [User: 2723.9 ms, System: 396.9 ms] 103 | Range (min … max): 840.2 ms … 1047.8 ms 10 runs 104 | 105 | Benchmark 4: oxfmt 106 | Time (mean ± σ): 370.2 ms ± 4.2 ms [User: 964.4 ms, System: 306.4 ms] 107 | Range (min … max): 363.7 ms … 378.3 ms 10 runs 108 | 109 | Summary 110 | oxfmt ran 111 | 2.40 ± 0.22 times faster than biome 112 | 18.87 ± 0.56 times faster than prettier+oxc-parser 113 | 26.09 ± 0.45 times faster than prettier 114 | 115 | Memory Usage: 116 | biome: 63.5 MB (min: 61.3 MB, max: 66.2 MB) 117 | oxfmt: 204.6 MB (min: 197.3 MB, max: 212.3 MB) 118 | 119 | Benchmark complete! 120 | ``` 121 | 122 | -------------------------------------------------------------------------------- /benchmark.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { execSync, spawn } from 'child_process'; 4 | import { existsSync } from 'fs'; 5 | 6 | // Constants 7 | const KB_TO_MB = 1024; 8 | const MEMORY_BENCHMARK_RUNS = 10; 9 | 10 | // Detect GNU time binary 11 | let gnuTimeBinary = null; 12 | try { 13 | execSync('gtime --version', { stdio: 'ignore' }); 14 | gnuTimeBinary = 'gtime'; 15 | } catch (e) { 16 | try { 17 | execSync('/usr/bin/time --version', { stdio: 'ignore' }); 18 | gnuTimeBinary = '/usr/bin/time'; 19 | } catch (e2) { 20 | // GNU time not available, will be checked in main() 21 | } 22 | } 23 | 24 | // Formatter commands 25 | // Target pure JS/TSX files with default config, disable embedded formatting 26 | const formatters = { 27 | prettier_format: (files) => 28 | `./node_modules/.bin/prettier ${files} --write --experimental-cli --embedded-language-formatting=off --ignore-path=.prettierignore --no-cache --ignore-unknown`, 29 | 30 | prettier_oxc_format: (files) => 31 | `./node_modules/.bin/prettier ${files} --write --experimental-cli --embedded-language-formatting=off --ignore-path=.prettierignore --no-cache --ignore-unknown --plugin @prettier/plugin-oxc`, 32 | 33 | biome_format: (files) => 34 | `./node_modules/.bin/biome format --write --files-ignore-unknown=true ${files}`, 35 | 36 | oxfmt_format: (files) => 37 | `./node_modules/.bin/oxfmt ${files}` 38 | }; 39 | 40 | // Memory measurement function 41 | // Uses GNU time (gtime on macOS, /usr/bin/time on Linux) to measure peak RSS memory. 42 | // gnuTimeBinary is set at module load time from a controlled check. 43 | // Formatter command strings are controlled by us (not user input). 44 | async function measureMemory(name, command, prepareCmd, runs = MEMORY_BENCHMARK_RUNS) { 45 | const measurements = []; 46 | 47 | for (let i = 0; i < runs; i++) { 48 | // Run prepare command if provided 49 | if (prepareCmd) { 50 | try { 51 | execSync(prepareCmd, { stdio: 'ignore' }); 52 | } catch (e) { 53 | // Ignore prepare errors 54 | } 55 | } 56 | 57 | // Run the command with GNU time to measure memory 58 | try { 59 | if (!gnuTimeBinary) { 60 | // Skip if GNU time is not available 61 | return null; 62 | } 63 | const escapedCommand = command.replace(/'/g, "'\\''"); 64 | const output = execSync( 65 | `${gnuTimeBinary} -f '%M' sh -c '${escapedCommand}' 2>&1 | tail -1`, 66 | { encoding: 'utf8', stdio: 'pipe' } 67 | ); 68 | const memKB = Number.parseInt(output.trim(), 10); 69 | if (!isNaN(memKB)) { 70 | measurements.push(memKB); 71 | } 72 | } catch (e) { 73 | // Continue on error 74 | } 75 | } 76 | 77 | if (measurements.length === 0) { 78 | return null; 79 | } 80 | 81 | // Calculate statistics 82 | measurements.sort((a, b) => a - b); 83 | const mean = measurements.reduce((a, b) => a + b, 0) / measurements.length; 84 | const min = measurements[0]; 85 | const max = measurements[measurements.length - 1]; 86 | 87 | return { 88 | name, 89 | mean: (mean / KB_TO_MB).toFixed(1), // Convert to MB 90 | min: (min / KB_TO_MB).toFixed(1), 91 | max: (max / KB_TO_MB).toFixed(1) 92 | }; 93 | } 94 | 95 | // Run hyperfine benchmark 96 | function runHyperfine(args) { 97 | return new Promise((resolve, reject) => { 98 | const proc = spawn('hyperfine', args, { stdio: 'inherit' }); 99 | proc.on('close', (code) => { 100 | if (code !== 0) { 101 | reject(new Error(`Hyperfine failed with code ${code}`)); 102 | } else { 103 | resolve(); 104 | } 105 | }); 106 | }); 107 | } 108 | 109 | // Run memory benchmarks 110 | async function runMemoryBenchmarks(benchmarks) { 111 | console.log(''); 112 | console.log('Memory Usage:'); 113 | 114 | const results = []; 115 | for (const bench of benchmarks) { 116 | const result = await measureMemory( 117 | bench.name, 118 | bench.command, 119 | bench.prepare, 120 | MEMORY_BENCHMARK_RUNS 121 | ); 122 | if (result) { 123 | results.push(result); 124 | } 125 | } 126 | 127 | // Print results 128 | for (const result of results) { 129 | console.log(` ${result.name}: ${result.mean} MB (min: ${result.min} MB, max: ${result.max} MB)`); 130 | } 131 | 132 | return results; 133 | } 134 | 135 | // Main async function 136 | async function main() { 137 | // Run setup script 138 | console.log('Running setup...'); 139 | execSync('./setup.sh', { stdio: 'inherit' }); 140 | 141 | console.log('========================================='); 142 | console.log('JavaScript/TypeScript Formatter Benchmark'); 143 | console.log('========================================='); 144 | console.log(''); 145 | console.log('Formatters: Prettier, Biome, Oxfmt'); 146 | console.log(''); 147 | 148 | // Check if outline directory exists 149 | if (!existsSync('outline')) { 150 | console.error('Error: Outline repository not found!'); 151 | console.error("Please run 'pnpm run setup' first"); 152 | process.exit(1); 153 | } 154 | 155 | // Check if node_modules exists 156 | if (!existsSync('node_modules')) { 157 | console.error('Error: Dependencies not installed!'); 158 | console.error("Please run 'pnpm run setup' first"); 159 | process.exit(1); 160 | } 161 | 162 | // Check if GNU time is available 163 | if (!gnuTimeBinary) { 164 | console.warn('Warning: GNU time not found. Memory benchmarking will be skipped.'); 165 | console.warn('Install GNU time to enable memory benchmarking:'); 166 | console.warn(' macOS: brew install gnu-time (installs as gtime)'); 167 | console.warn(' Linux: apt install time or yum install time'); 168 | } 169 | 170 | console.log('Starting benchmark with:'); 171 | console.log('- 3 warmup runs'); 172 | console.log('- 10 benchmark runs'); 173 | console.log('- Git reset before each run'); 174 | console.log(''); 175 | 176 | // Benchmark parser.ts 177 | console.log(''); 178 | console.log('========================================='); 179 | console.log('Benchmarking parser.ts (single large file)'); 180 | console.log('========================================='); 181 | 182 | try { 183 | await runHyperfine([ 184 | '--ignore-failure', 185 | '--warmup', '3', 186 | '--runs', '10', 187 | '--prepare', 'cp parser.ts.bak parser.ts', 188 | '--shell=bash', 189 | '-n', 'prettier', 190 | '-n', 'prettier+oxc-parser', 191 | '-n', 'biome', 192 | '-n', 'oxfmt', 193 | formatters.prettier_format('parser.ts'), 194 | formatters.prettier_oxc_format('parser.ts'), 195 | formatters.biome_format('parser.ts'), 196 | formatters.oxfmt_format('parser.ts') 197 | ]); 198 | 199 | // Memory benchmarks for parser.ts 200 | await runMemoryBenchmarks([ 201 | { name: 'prettier', command: formatters.prettier_format('parser.ts'), prepare: 'cp parser.ts.bak parser.ts' }, 202 | { name: 'prettier+oxc-parser', command: formatters.prettier_oxc_format('parser.ts'), prepare: 'cp parser.ts.bak parser.ts' }, 203 | { name: 'biome', command: formatters.biome_format('parser.ts'), prepare: 'cp parser.ts.bak parser.ts' }, 204 | { name: 'oxfmt', command: formatters.oxfmt_format('parser.ts'), prepare: 'cp parser.ts.bak parser.ts' } 205 | ]); 206 | } catch (e) { 207 | console.error(`Parser benchmark failed: ${e.message}`); 208 | } 209 | 210 | // Benchmark Outline repository 211 | console.log(''); 212 | console.log('========================================='); 213 | console.log('Benchmarking Outline repository'); 214 | console.log('========================================='); 215 | 216 | try { 217 | await runHyperfine([ 218 | '--ignore-failure', 219 | '--warmup', '3', 220 | '--runs', '10', 221 | '--prepare', 'git -C outline reset --hard', 222 | '--shell=bash', 223 | '-n', 'prettier', 224 | '-n', 'prettier+oxc-parser', 225 | '-n', 'biome', 226 | '-n', 'oxfmt', 227 | formatters.prettier_format('"outline/**/*.{js,jsx,ts,tsx}"'), 228 | formatters.prettier_oxc_format('"outline/**/*.{js,jsx,ts,tsx}"'), 229 | formatters.biome_format('outline'), 230 | formatters.oxfmt_format('outline') 231 | ]); 232 | 233 | // Memory benchmarks for Outline 234 | await runMemoryBenchmarks([ 235 | { name: 'prettier', command: formatters.prettier_format('"outline/**/*.{js,jsx,ts,tsx}"'), prepare: 'git -C outline reset --hard' }, 236 | { name: 'prettier+oxc-parser', command: formatters.prettier_oxc_format('"outline/**/*.{js,jsx,ts,tsx}"'), prepare: 'git -C outline reset --hard' }, 237 | { name: 'biome', command: formatters.biome_format('outline'), prepare: 'git -C outline reset --hard' }, 238 | { name: 'oxfmt', command: formatters.oxfmt_format('outline'), prepare: 'git -C outline reset --hard' } 239 | ]); 240 | } catch (e) { 241 | console.error(`Outline benchmark failed: ${e.message}`); 242 | } 243 | 244 | console.log(''); 245 | console.log('Benchmark complete!'); 246 | } 247 | 248 | // Run main function 249 | main().catch(error => { 250 | console.error('Error:', error); 251 | process.exit(1); 252 | }); 253 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | devDependencies: 11 | '@biomejs/biome': 12 | specifier: ^2.3.8 13 | version: 2.3.8 14 | '@prettier/plugin-oxc': 15 | specifier: ^0.1.2 16 | version: 0.1.3 17 | oxfmt: 18 | specifier: ^0.19.0 19 | version: 0.19.0 20 | prettier: 21 | specifier: ^3.7.3 22 | version: 3.7.4 23 | 24 | packages: 25 | 26 | '@biomejs/biome@2.3.8': 27 | resolution: {integrity: sha512-Qjsgoe6FEBxWAUzwFGFrB+1+M8y/y5kwmg5CHac+GSVOdmOIqsAiXM5QMVGZJ1eCUCLlPZtq4aFAQ0eawEUuUA==} 28 | engines: {node: '>=14.21.3'} 29 | hasBin: true 30 | 31 | '@biomejs/cli-darwin-arm64@2.3.8': 32 | resolution: {integrity: sha512-HM4Zg9CGQ3txTPflxD19n8MFPrmUAjaC7PQdLkugeeC0cQ+PiVrd7i09gaBS/11QKsTDBJhVg85CEIK9f50Qww==} 33 | engines: {node: '>=14.21.3'} 34 | cpu: [arm64] 35 | os: [darwin] 36 | 37 | '@biomejs/cli-darwin-x64@2.3.8': 38 | resolution: {integrity: sha512-lUDQ03D7y/qEao7RgdjWVGCu+BLYadhKTm40HkpJIi6kn8LSv5PAwRlew/DmwP4YZ9ke9XXoTIQDO1vAnbRZlA==} 39 | engines: {node: '>=14.21.3'} 40 | cpu: [x64] 41 | os: [darwin] 42 | 43 | '@biomejs/cli-linux-arm64-musl@2.3.8': 44 | resolution: {integrity: sha512-PShR4mM0sjksUMyxbyPNMxoKFPVF48fU8Qe8Sfx6w6F42verbwRLbz+QiKNiDPRJwUoMG1nPM50OBL3aOnTevA==} 45 | engines: {node: '>=14.21.3'} 46 | cpu: [arm64] 47 | os: [linux] 48 | 49 | '@biomejs/cli-linux-arm64@2.3.8': 50 | resolution: {integrity: sha512-Uo1OJnIkJgSgF+USx970fsM/drtPcQ39I+JO+Fjsaa9ZdCN1oysQmy6oAGbyESlouz+rzEckLTF6DS7cWse95g==} 51 | engines: {node: '>=14.21.3'} 52 | cpu: [arm64] 53 | os: [linux] 54 | 55 | '@biomejs/cli-linux-x64-musl@2.3.8': 56 | resolution: {integrity: sha512-YGLkqU91r1276uwSjiUD/xaVikdxgV1QpsicT0bIA1TaieM6E5ibMZeSyjQ/izBn4tKQthUSsVZacmoJfa3pDA==} 57 | engines: {node: '>=14.21.3'} 58 | cpu: [x64] 59 | os: [linux] 60 | 61 | '@biomejs/cli-linux-x64@2.3.8': 62 | resolution: {integrity: sha512-QDPMD5bQz6qOVb3kiBui0zKZXASLo0NIQ9JVJio5RveBEFgDgsvJFUvZIbMbUZT3T00M/1wdzwWXk4GIh0KaAw==} 63 | engines: {node: '>=14.21.3'} 64 | cpu: [x64] 65 | os: [linux] 66 | 67 | '@biomejs/cli-win32-arm64@2.3.8': 68 | resolution: {integrity: sha512-H4IoCHvL1fXKDrTALeTKMiE7GGWFAraDwBYFquE/L/5r1927Te0mYIGseXi4F+lrrwhSWbSGt5qPFswNoBaCxg==} 69 | engines: {node: '>=14.21.3'} 70 | cpu: [arm64] 71 | os: [win32] 72 | 73 | '@biomejs/cli-win32-x64@2.3.8': 74 | resolution: {integrity: sha512-RguzimPoZWtBapfKhKjcWXBVI91tiSprqdBYu7tWhgN8pKRZhw24rFeNZTNf6UiBfjCYCi9eFQs/JzJZIhuK4w==} 75 | engines: {node: '>=14.21.3'} 76 | cpu: [x64] 77 | os: [win32] 78 | 79 | '@emnapi/core@1.7.1': 80 | resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} 81 | 82 | '@emnapi/runtime@1.7.1': 83 | resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} 84 | 85 | '@emnapi/wasi-threads@1.1.0': 86 | resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} 87 | 88 | '@napi-rs/wasm-runtime@1.1.0': 89 | resolution: {integrity: sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==} 90 | 91 | '@oxc-parser/binding-android-arm64@0.99.0': 92 | resolution: {integrity: sha512-V4jhmKXgQQdRnm73F+r3ZY4pUEsijQeSraFeaCGng7abSNJGs76X6l82wHnmjLGFAeY00LWtjcELs7ZmbJ9+lA==} 93 | engines: {node: ^20.19.0 || >=22.12.0} 94 | cpu: [arm64] 95 | os: [android] 96 | 97 | '@oxc-parser/binding-darwin-arm64@0.99.0': 98 | resolution: {integrity: sha512-Rp41nf9zD5FyLZciS9l1GfK8PhYqrD5kEGxyTOA2esTLeAy37rZxetG2E3xteEolAkeb2WDkVrlxPtibeAncMg==} 99 | engines: {node: ^20.19.0 || >=22.12.0} 100 | cpu: [arm64] 101 | os: [darwin] 102 | 103 | '@oxc-parser/binding-darwin-x64@0.99.0': 104 | resolution: {integrity: sha512-WVonp40fPPxo5Gs0POTI57iEFv485TvNKOHMwZRhigwZRhZY2accEAkYIhei9eswF4HN5B44Wybkz7Gd1Qr/5Q==} 105 | engines: {node: ^20.19.0 || >=22.12.0} 106 | cpu: [x64] 107 | os: [darwin] 108 | 109 | '@oxc-parser/binding-freebsd-x64@0.99.0': 110 | resolution: {integrity: sha512-H30bjOOttPmG54gAqu6+HzbLEzuNOYO2jZYrIq4At+NtLJwvNhXz28Hf5iEAFZIH/4hMpLkM4VN7uc+5UlNW3Q==} 111 | engines: {node: ^20.19.0 || >=22.12.0} 112 | cpu: [x64] 113 | os: [freebsd] 114 | 115 | '@oxc-parser/binding-linux-arm-gnueabihf@0.99.0': 116 | resolution: {integrity: sha512-0Z/Th0SYqzSRDPs6tk5lQdW0i73UCupnim3dgq2oW0//UdLonV/5wIZCArfKGC7w9y4h8TxgXpgtIyD1kKzzlQ==} 117 | engines: {node: ^20.19.0 || >=22.12.0} 118 | cpu: [arm] 119 | os: [linux] 120 | 121 | '@oxc-parser/binding-linux-arm-musleabihf@0.99.0': 122 | resolution: {integrity: sha512-xo0wqNd5bpbzQVNpAIFbHk1xa+SaS/FGBABCd942SRTnrpxl6GeDj/s1BFaGcTl8MlwlKVMwOcyKrw/2Kdfquw==} 123 | engines: {node: ^20.19.0 || >=22.12.0} 124 | cpu: [arm] 125 | os: [linux] 126 | 127 | '@oxc-parser/binding-linux-arm64-gnu@0.99.0': 128 | resolution: {integrity: sha512-u26I6LKoLTPTd4Fcpr0aoAtjnGf5/ulMllo+QUiBhupgbVCAlaj4RyXH/mvcjcsl2bVBv9E/gYJZz2JjxQWXBA==} 129 | engines: {node: ^20.19.0 || >=22.12.0} 130 | cpu: [arm64] 131 | os: [linux] 132 | 133 | '@oxc-parser/binding-linux-arm64-musl@0.99.0': 134 | resolution: {integrity: sha512-qhftDo2D37SqCEl3ZTa367NqWSZNb1Ddp34CTmShLKFrnKdNiUn55RdokLnHtf1AL5ssaQlYDwBECX7XiBWOhw==} 135 | engines: {node: ^20.19.0 || >=22.12.0} 136 | cpu: [arm64] 137 | os: [linux] 138 | 139 | '@oxc-parser/binding-linux-riscv64-gnu@0.99.0': 140 | resolution: {integrity: sha512-zxn/xkf519f12FKkpL5XwJipsylfSSnm36h6c1zBDTz4fbIDMGyIhHfWfwM7uUmHo9Aqw1pLxFpY39Etv398+Q==} 141 | engines: {node: ^20.19.0 || >=22.12.0} 142 | cpu: [riscv64] 143 | os: [linux] 144 | 145 | '@oxc-parser/binding-linux-s390x-gnu@0.99.0': 146 | resolution: {integrity: sha512-Y1eSDKDS5E4IVC7Oxw+NbYAKRmJPMJTIjW+9xOWwteDHkFqpocKe0USxog+Q1uhzalD9M0p9eXWEWdGQCMDBMQ==} 147 | engines: {node: ^20.19.0 || >=22.12.0} 148 | cpu: [s390x] 149 | os: [linux] 150 | 151 | '@oxc-parser/binding-linux-x64-gnu@0.99.0': 152 | resolution: {integrity: sha512-YVJMfk5cFWB8i2/nIrbk6n15bFkMHqWnMIWkVx7r2KwpTxHyFMfu2IpeVKo1ITDSmt5nBrGdLHD36QRlu2nDLg==} 153 | engines: {node: ^20.19.0 || >=22.12.0} 154 | cpu: [x64] 155 | os: [linux] 156 | 157 | '@oxc-parser/binding-linux-x64-musl@0.99.0': 158 | resolution: {integrity: sha512-2+SDPrie5f90A1b9EirtVggOgsqtsYU5raZwkDYKyS1uvJzjqHCDhG/f4TwQxHmIc5YkczdQfwvN91lwmjsKYQ==} 159 | engines: {node: ^20.19.0 || >=22.12.0} 160 | cpu: [x64] 161 | os: [linux] 162 | 163 | '@oxc-parser/binding-wasm32-wasi@0.99.0': 164 | resolution: {integrity: sha512-DKA4j0QerUWSMADziLM5sAyM7V53Fj95CV9SjP77bPfEfT7MnvFKnneaRMqPK1cpzjAGiQF52OBUIKyk0dwOQA==} 165 | engines: {node: '>=14.0.0'} 166 | cpu: [wasm32] 167 | 168 | '@oxc-parser/binding-win32-arm64-msvc@0.99.0': 169 | resolution: {integrity: sha512-EaB3AvsxqdNUhh9FOoAxRZ2L4PCRwDlDb//QXItwyOJrX7XS+uGK9B1KEUV4FZ/7rDhHsWieLt5e07wl2Ti5AQ==} 170 | engines: {node: ^20.19.0 || >=22.12.0} 171 | cpu: [arm64] 172 | os: [win32] 173 | 174 | '@oxc-parser/binding-win32-x64-msvc@0.99.0': 175 | resolution: {integrity: sha512-sJN1Q8h7ggFOyDn0zsHaXbP/MklAVUvhrbq0LA46Qum686P3SZQHjbATqJn9yaVEvaSKXCshgl0vQ1gWkGgpcQ==} 176 | engines: {node: ^20.19.0 || >=22.12.0} 177 | cpu: [x64] 178 | os: [win32] 179 | 180 | '@oxc-project/types@0.99.0': 181 | resolution: {integrity: sha512-LLDEhXB7g1m5J+woRSgfKsFPS3LhR9xRhTeIoEBm5WrkwMxn6eZ0Ld0c0K5eHB57ChZX6I3uSmmLjZ8pcjlRcw==} 182 | 183 | '@oxfmt/darwin-arm64@0.19.0': 184 | resolution: {integrity: sha512-FfNpn3ximwbBZCaS8WL2vAXcFuQFQgvv/brO6D1WdmL4pnFOgfBIpFfkeFnKfdmdpxtg9O0wF8NTcdw5Iyl2Bg==} 185 | cpu: [arm64] 186 | os: [darwin] 187 | 188 | '@oxfmt/darwin-x64@0.19.0': 189 | resolution: {integrity: sha512-31FWUHAgTdTzOslz0zoA60UDEdeZZpeM6wTzCdffetwLbHkK8ZuCuzd+DauHZPNlSU8G72iw4lF7Zve9pSkK9w==} 190 | cpu: [x64] 191 | os: [darwin] 192 | 193 | '@oxfmt/linux-arm64-gnu@0.19.0': 194 | resolution: {integrity: sha512-BkU9h39xKj/8uko82uFDJUharM8VxZO+uXKglpBnEC8XxWRzXocVCX4wpLT/Tfk4NyBy6fRM9DeISdZvQKZCjA==} 195 | cpu: [arm64] 196 | os: [linux] 197 | 198 | '@oxfmt/linux-arm64-musl@0.19.0': 199 | resolution: {integrity: sha512-wWYk6Z/3iC+0zZAUkVCcEHui/IsUqsl+GEm9o6H7oARPLisXajbwCQcmqYslUD7eK6OXdYoWriBkEvSX/5dU4A==} 200 | cpu: [arm64] 201 | os: [linux] 202 | 203 | '@oxfmt/linux-x64-gnu@0.19.0': 204 | resolution: {integrity: sha512-EB/b3or437E3uDie8QxeU3eA502JcmR1koyIBcH9rFidY0cMik58xvw54tXCY3WpMRxEXf37aHZzUSDP3qJnZg==} 205 | cpu: [x64] 206 | os: [linux] 207 | 208 | '@oxfmt/linux-x64-musl@0.19.0': 209 | resolution: {integrity: sha512-htMB45orYoa1oFSjSmoGgcBDsD47/0joDfqpa8TrTDI5qsW5kAedpFR5wSce8Is9oj7SJ07omhOj96P/QiekWA==} 210 | cpu: [x64] 211 | os: [linux] 212 | 213 | '@oxfmt/win32-arm64@0.19.0': 214 | resolution: {integrity: sha512-x7+3Eh/VWdXEda+BUmAKYlhGrRJVera7RfWw47Yx8PJUGtNqBfeYGDbf0W59ceK8Z3bY3OinrmOO3d1jOuXzMQ==} 215 | cpu: [arm64] 216 | os: [win32] 217 | 218 | '@oxfmt/win32-x64@0.19.0': 219 | resolution: {integrity: sha512-X+FKXBg2jx4CxF5SJs3xpx1msMw5JfxaGD5qBZYqlHGdryQsy6zUY+bQwDDcuy3Ic/WNGD8ZNEuggeYNE7jx/Q==} 220 | cpu: [x64] 221 | os: [win32] 222 | 223 | '@prettier/plugin-oxc@0.1.3': 224 | resolution: {integrity: sha512-aABz3zIRilpWMekbt1FL1JVBQrQLR8L4Td2SRctECrWSsXGTNn/G1BqNSKCdbvQS1LWstAXfqcXzDki7GAAJyg==} 225 | engines: {node: '>=14'} 226 | 227 | '@tybys/wasm-util@0.10.1': 228 | resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} 229 | 230 | oxc-parser@0.99.0: 231 | resolution: {integrity: sha512-MpS1lbd2vR0NZn1v0drpgu7RUFu3x9Rd0kxExObZc2+F+DIrV0BOMval/RO3BYGwssIOerII6iS8EbbpCCZQpQ==} 232 | engines: {node: ^20.19.0 || >=22.12.0} 233 | 234 | oxfmt@0.19.0: 235 | resolution: {integrity: sha512-tPTa3j4kXdJBzBRlK9wR0/Lnd4J21rzg29cRr/VVqqfvdhZs6M+Q6TkL+rxI/IQpq8ZY8L3c+KZvga/RgeuMsg==} 236 | engines: {node: ^20.19.0 || >=22.12.0} 237 | hasBin: true 238 | 239 | prettier@3.7.4: 240 | resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} 241 | engines: {node: '>=14'} 242 | hasBin: true 243 | 244 | tinypool@2.0.0: 245 | resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} 246 | engines: {node: ^20.0.0 || >=22.0.0} 247 | 248 | tslib@2.8.1: 249 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 250 | 251 | snapshots: 252 | 253 | '@biomejs/biome@2.3.8': 254 | optionalDependencies: 255 | '@biomejs/cli-darwin-arm64': 2.3.8 256 | '@biomejs/cli-darwin-x64': 2.3.8 257 | '@biomejs/cli-linux-arm64': 2.3.8 258 | '@biomejs/cli-linux-arm64-musl': 2.3.8 259 | '@biomejs/cli-linux-x64': 2.3.8 260 | '@biomejs/cli-linux-x64-musl': 2.3.8 261 | '@biomejs/cli-win32-arm64': 2.3.8 262 | '@biomejs/cli-win32-x64': 2.3.8 263 | 264 | '@biomejs/cli-darwin-arm64@2.3.8': 265 | optional: true 266 | 267 | '@biomejs/cli-darwin-x64@2.3.8': 268 | optional: true 269 | 270 | '@biomejs/cli-linux-arm64-musl@2.3.8': 271 | optional: true 272 | 273 | '@biomejs/cli-linux-arm64@2.3.8': 274 | optional: true 275 | 276 | '@biomejs/cli-linux-x64-musl@2.3.8': 277 | optional: true 278 | 279 | '@biomejs/cli-linux-x64@2.3.8': 280 | optional: true 281 | 282 | '@biomejs/cli-win32-arm64@2.3.8': 283 | optional: true 284 | 285 | '@biomejs/cli-win32-x64@2.3.8': 286 | optional: true 287 | 288 | '@emnapi/core@1.7.1': 289 | dependencies: 290 | '@emnapi/wasi-threads': 1.1.0 291 | tslib: 2.8.1 292 | optional: true 293 | 294 | '@emnapi/runtime@1.7.1': 295 | dependencies: 296 | tslib: 2.8.1 297 | optional: true 298 | 299 | '@emnapi/wasi-threads@1.1.0': 300 | dependencies: 301 | tslib: 2.8.1 302 | optional: true 303 | 304 | '@napi-rs/wasm-runtime@1.1.0': 305 | dependencies: 306 | '@emnapi/core': 1.7.1 307 | '@emnapi/runtime': 1.7.1 308 | '@tybys/wasm-util': 0.10.1 309 | optional: true 310 | 311 | '@oxc-parser/binding-android-arm64@0.99.0': 312 | optional: true 313 | 314 | '@oxc-parser/binding-darwin-arm64@0.99.0': 315 | optional: true 316 | 317 | '@oxc-parser/binding-darwin-x64@0.99.0': 318 | optional: true 319 | 320 | '@oxc-parser/binding-freebsd-x64@0.99.0': 321 | optional: true 322 | 323 | '@oxc-parser/binding-linux-arm-gnueabihf@0.99.0': 324 | optional: true 325 | 326 | '@oxc-parser/binding-linux-arm-musleabihf@0.99.0': 327 | optional: true 328 | 329 | '@oxc-parser/binding-linux-arm64-gnu@0.99.0': 330 | optional: true 331 | 332 | '@oxc-parser/binding-linux-arm64-musl@0.99.0': 333 | optional: true 334 | 335 | '@oxc-parser/binding-linux-riscv64-gnu@0.99.0': 336 | optional: true 337 | 338 | '@oxc-parser/binding-linux-s390x-gnu@0.99.0': 339 | optional: true 340 | 341 | '@oxc-parser/binding-linux-x64-gnu@0.99.0': 342 | optional: true 343 | 344 | '@oxc-parser/binding-linux-x64-musl@0.99.0': 345 | optional: true 346 | 347 | '@oxc-parser/binding-wasm32-wasi@0.99.0': 348 | dependencies: 349 | '@napi-rs/wasm-runtime': 1.1.0 350 | optional: true 351 | 352 | '@oxc-parser/binding-win32-arm64-msvc@0.99.0': 353 | optional: true 354 | 355 | '@oxc-parser/binding-win32-x64-msvc@0.99.0': 356 | optional: true 357 | 358 | '@oxc-project/types@0.99.0': {} 359 | 360 | '@oxfmt/darwin-arm64@0.19.0': 361 | optional: true 362 | 363 | '@oxfmt/darwin-x64@0.19.0': 364 | optional: true 365 | 366 | '@oxfmt/linux-arm64-gnu@0.19.0': 367 | optional: true 368 | 369 | '@oxfmt/linux-arm64-musl@0.19.0': 370 | optional: true 371 | 372 | '@oxfmt/linux-x64-gnu@0.19.0': 373 | optional: true 374 | 375 | '@oxfmt/linux-x64-musl@0.19.0': 376 | optional: true 377 | 378 | '@oxfmt/win32-arm64@0.19.0': 379 | optional: true 380 | 381 | '@oxfmt/win32-x64@0.19.0': 382 | optional: true 383 | 384 | '@prettier/plugin-oxc@0.1.3': 385 | dependencies: 386 | oxc-parser: 0.99.0 387 | 388 | '@tybys/wasm-util@0.10.1': 389 | dependencies: 390 | tslib: 2.8.1 391 | optional: true 392 | 393 | oxc-parser@0.99.0: 394 | dependencies: 395 | '@oxc-project/types': 0.99.0 396 | optionalDependencies: 397 | '@oxc-parser/binding-android-arm64': 0.99.0 398 | '@oxc-parser/binding-darwin-arm64': 0.99.0 399 | '@oxc-parser/binding-darwin-x64': 0.99.0 400 | '@oxc-parser/binding-freebsd-x64': 0.99.0 401 | '@oxc-parser/binding-linux-arm-gnueabihf': 0.99.0 402 | '@oxc-parser/binding-linux-arm-musleabihf': 0.99.0 403 | '@oxc-parser/binding-linux-arm64-gnu': 0.99.0 404 | '@oxc-parser/binding-linux-arm64-musl': 0.99.0 405 | '@oxc-parser/binding-linux-riscv64-gnu': 0.99.0 406 | '@oxc-parser/binding-linux-s390x-gnu': 0.99.0 407 | '@oxc-parser/binding-linux-x64-gnu': 0.99.0 408 | '@oxc-parser/binding-linux-x64-musl': 0.99.0 409 | '@oxc-parser/binding-wasm32-wasi': 0.99.0 410 | '@oxc-parser/binding-win32-arm64-msvc': 0.99.0 411 | '@oxc-parser/binding-win32-x64-msvc': 0.99.0 412 | 413 | oxfmt@0.19.0: 414 | dependencies: 415 | tinypool: 2.0.0 416 | optionalDependencies: 417 | '@oxfmt/darwin-arm64': 0.19.0 418 | '@oxfmt/darwin-x64': 0.19.0 419 | '@oxfmt/linux-arm64-gnu': 0.19.0 420 | '@oxfmt/linux-arm64-musl': 0.19.0 421 | '@oxfmt/linux-x64-gnu': 0.19.0 422 | '@oxfmt/linux-x64-musl': 0.19.0 423 | '@oxfmt/win32-arm64': 0.19.0 424 | '@oxfmt/win32-x64': 0.19.0 425 | 426 | prettier@3.7.4: {} 427 | 428 | tinypool@2.0.0: {} 429 | 430 | tslib@2.8.1: 431 | optional: true 432 | --------------------------------------------------------------------------------