sort-package-json 0.0.5

A Rust implementation of sort-package-json that sorts package.json files according to well-established npm conventions
Documentation
<div align="center">

# sort-package-json

[![Crates.io][crates-badge]][crates-url]
[![Docs.rs][docs-badge]][docs-url]

[![MIT licensed][license-badge]][license-url]
[![Build Status][ci-badge]][ci-url]
[![Code Coverage][code-coverage-badge]][code-coverage-url]
[![CodSpeed Badge][codspeed-badge]][codspeed-url]
[![Sponsors][sponsors-badge]][sponsors-url]
[![Discord chat][discord-badge]][discord-url]

</div>

A Rust implementation of [sort-package-json](https://github.com/keithamus/sort-package-json) that sorts package.json files according to well-established npm conventions.

## Features

- **Sorts top-level fields** according to npm ecosystem conventions (138 predefined fields)
- **Preserves all data** - only reorders fields, never modifies values
- **Fast and safe** - pure Rust implementation with no unsafe code
- **Idempotent** - sorting multiple times produces the same result
- **Handles edge cases** - unknown fields sorted alphabetically, private fields (starting with `_`) sorted last

## Usage

```bash
cargo run
```

The tool will recursively find all `package.json` files in the current directory and sort them in place.

### Example

Given an unsorted package.json:

```json
{
  "version": "1.0.0",
  "dependencies": { ... },
  "name": "my-package",
  "scripts": { ... }
}
```

Running `cargo run package.json` produces:

```json
{
  "name": "my-package",
  "version": "1.0.0",
  "scripts": { ... },
  "dependencies": { ... }
}
```

## Field Ordering

Fields are sorted according to this priority:

1. **Known fields** - 138 predefined fields organized into 12 logical groups
2. **Unknown fields** - any custom fields sorted alphabetically
3. **Private fields** - fields starting with `_` sorted alphabetically at the end

The complete field order is based on both the [original sort-package-json](https://github.com/keithamus/sort-package-json/blob/main/index.js) and [prettier's package.json sorting](https://github.com/un-ts/prettier/blob/master/packages/pkg/src/rules/sort.ts) implementations.

### Known Field Groups

#### 1. Core Package Metadata
`$schema`, `name`, `displayName`, `version`, `stableVersion`, `gitHead`, `private`, `description`, `categories`, `keywords`, `homepage`, `bugs`

#### 2. License & People
`license`, `author`, `maintainers`, `contributors`

#### 3. Repository & Funding
`repository`, `funding`, `donate`, `sponsor`, `qna`, `publisher`

#### 4. Package Content & Distribution
`man`, `style`, `example`, `examplestyle`, `assets`, `bin`, `source`, `directories`, `workspaces`, `binary`, `files`, `os`, `cpu`, `libc`

#### 5. Package Entry Points
`type`, `sideEffects`, `main`, `module`, `browser`, `types`, `typings`, `typesVersions`, `typeScriptVersion`, `typesPublisherContentHash`, `react-native`, `svelte`, `unpkg`, `jsdelivr`, `jsnext:main`, `umd`, `umd:main`, `es5`, `esm5`, `fesm5`, `es2015`, `esm2015`, `fesm2015`, `es2020`, `esm2020`, `fesm2020`, `esnext`, `imports`, `exports`, `publishConfig`

#### 6. Scripts
`scripts`, `betterScripts`

#### 7. Dependencies
`dependencies`, `devDependencies`, `dependenciesMeta`, `peerDependencies`, `peerDependenciesMeta`, `optionalDependencies`, `bundledDependencies`, `bundleDependencies`, `resolutions`, `overrides`

#### 8. Git Hooks & Commit Tools
`husky`, `simple-git-hooks`, `pre-commit`, `lint-staged`, `nano-staged`, `commitlint`

#### 9. VSCode Extension Specific
`l10n`, `contributes`, `activationEvents`, `extensionPack`, `extensionDependencies`, `extensionKind`, `icon`, `badges`, `galleryBanner`, `preview`, `markdown`

#### 10. Build & Tool Configuration
`napi`, `flat`, `config`, `nodemonConfig`, `browserify`, `babel`, `browserslist`, `xo`, `prettier`, `eslintConfig`, `eslintIgnore`, `standard`, `npmpkgjsonlint`, `npmPackageJsonLintConfig`, `npmpackagejsonlint`, `release`, `auto-changelog`, `remarkConfig`, `stylelint`, `typescript`, `typedoc`, `tshy`, `tsdown`, `size-limit`

#### 11. Testing
`ava`, `jest`, `jest-junit`, `jest-stare`, `mocha`, `nyc`, `c8`, `tap`, `tsd`, `typeCoverage`, `oclif`

#### 12. Runtime & Package Manager
`languageName`, `preferGlobal`, `devEngines`, `engines`, `engineStrict`, `volta`, `packageManager`, `pnpm`

## Why Not simd-json?

While investigating performance optimizations, we considered using [simd-json](https://github.com/simd-lite/simd-json) instead of serde_json. However, simd-json is not suitable for this project due to several technical limitations:

### 1. No preserve_order Support

Our sorting algorithm requires maintaining custom insertion order. We insert fields in a specific sequence (known fields � unknown fields � private fields) and need the Map to preserve that exact order during serialization.

simd-json lacks the equivalent of serde_json's `preserve_order` feature, which uses IndexMap to maintain insertion order. Without this, the Map implementation would re-sort keys alphabetically, completely breaking our field ordering logic.

**Status**: Blocking issue - makes simd-json incompatible with our core functionality.

### 2. Wrong Performance Profile

simd-json is optimized for **large files** (1MB+) through SIMD acceleration, but is **slower for small files** due to SIMD overhead:

- For small objects: serde_json is **1.6x faster**
- For large objects (1.8MB): simd-json is **3x faster**

Package.json files are typically **1-5 KB**, rarely exceeding 50 KB even for large monorepos. This makes them squarely in the "small file" category where simd-json would actually **decrease performance**.

### 3. Platform Compatibility Issues

simd-json does not work correctly on **big-endian architectures** (e.g., s390x/IBM Z mainframe). Projects using simd-json must implement conditional compilation to fall back to serde_json on big-endian platforms.

See [simd-json issue #437](https://github.com/simd-lite/simd-json/issues/437) for details.

### 4. Additional Complexity

- Contains substantial **unsafe code** (C++ port)
- Requires specific allocators (mimalloc/jemalloc) for optimal performance
- More complex dependency tree

### Conclusion

For a package.json sorting tool, **serde_json is the optimal choice**:

-  Faster for small files (our use case)
-  Supports preserve_order (required feature)
-  Safe, stable, cross-platform
-  Simpler dependency tree
-  No platform-specific limitations

## Development

### Building

```bash
cargo build --release
```

### Running Tests

```bash
cargo test
```

Tests use snapshot testing via [insta](https://insta.rs/). To review and accept snapshot changes:

```bash
cargo insta review
```

Or to accept all changes:

```bash
cargo insta accept
```

### Test Coverage

- **Field ordering test** - verifies correct sorting of all field types
- **Idempotency test** - ensures sorting is stable (sorting twice = sorting once)

## License

MIT

## References

- [Original sort-package-json (JavaScript)]https://github.com/keithamus/sort-package-json
- [simd-json issue #437 - Big Endian Compatibility]https://github.com/simd-lite/simd-json/issues/437
- [Surprises in the Rust JSON Ecosystem]https://ecton.dev/rust-json-ecosystem/

## [Sponsored By]https://github.com/sponsors/Boshen

<p align="center">
  <a href="https://github.com/sponsors/Boshen">
    <img src="https://raw.githubusercontent.com/Boshen/sponsors/main/sponsors.svg" alt="My sponsors" />
  </a>
</p>

[discord-badge]: https://img.shields.io/discord/1079625926024900739?logo=discord&label=Discord
[discord-url]: https://discord.gg/9uXCAwqQZW
[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg
[license-url]: https://github.com/oxc-project/sort-package-json/blob/main/LICENSE
[ci-badge]: https://github.com/oxc-project/sort-package-json/actions/workflows/ci.yml/badge.svg?event=push&branch=main
[ci-url]: https://github.com/oxc-project/sort-package-json/actions/workflows/ci.yml?query=event%3Apush+branch%3Amain
[code-coverage-badge]: https://codecov.io/github/oxc-project/sort-package-json/branch/main/graph/badge.svg
[code-coverage-url]: https://codecov.io/gh/oxc-project/sort-package-json
[sponsors-badge]: https://img.shields.io/github/sponsors/Boshen
[sponsors-url]: https://github.com/sponsors/Boshen
[codspeed-badge]: https://img.shields.io/endpoint?url=https://codspeed.io/badge.json
[codspeed-url]: https://codspeed.io/oxc-project/sort-package-json
[crates-badge]: https://img.shields.io/crates/d/sort-package-json?label=crates.io
[crates-url]: https://crates.io/crates/sort-package-json
[docs-badge]: https://img.shields.io/docsrs/sort-package-json
[docs-url]: https://docs.rs/sort-package-json