adotenv 0.10.3

A tooling-grade .env parser: literal values (no variable expansion), exact byte spans, and edits that leave the rest of the file untouched.
Documentation
# Competitive analysis

This document compares adotenv with common Rust `.env` parsers and loaders. The
goal is to identify concrete work, not to rank libraries on a single number.

## Comparison set

- `adotenv` 0.10.3
- `dotenvy` 0.15.7
- `dotenv` 0.15.0
- `dotenv-compat` 0.4.0
- `dotenv-ng-core` 1.0.0
- `dotenv-parser` 0.1.3
- `dotenv-linter` 4.0.0 for CLI comparison

## Method

Benchmarks use a release build on Linux x86_64. The fixture has 65,536 simple
`KEY=value` entries and a 1.4 MB source. Each library reads the source before
measurement, parses it, and builds a map where the library supports one.

- Wall time: `hyperfine`, five process runs, multiple parses per run, using the
  median process time.
- Instructions: Valgrind callgrind, one parse, with a no-op baseline.
- Memory: `/proc/self/status` high-water mark and retained RSS, with a no-op
  baseline.
- Binary size: stripped release binary with thin LTO for a parse-and-print
  program.
- Dependencies and MSRV: crates.io metadata.

Run `python3 scripts/compare.py --update-doc` to regenerate the benchmark
section on an idle host.

## Results

<!-- BEGIN GENERATED BENCHMARKS -->
Generated by `python3 scripts/compare.py`.

### Parse and map build

Per parse on the 65,536-entry fixture:

| Implementation | Wall time | Instructions | Peak RSS | Retained RSS |
|---|---:|---:|---:|---:|
| adotenv parse | 31.9 ms | 234M | 26.6 MB | 26.6 MB |
| adotenv parse + values | 42.8 ms | 363M | 10.0 MB | 10.0 MB |
| adotenv parse + map | 38.8 ms | 301M | 32.4 MB | 14.4 MB |
| dotenvy iterator + map | 72.6 ms | 354M | 18.9 MB | 11.4 MB |
| dotenv-compat parse | 48.7 ms | 265M | 19.8 MB | 14.5 MB |
| dotenv-ng input-only | 126.8 ms | 378M | 26.5 MB | 20.5 MB |
| dotenv-parser map | 140.7 ms | 1239M | 25.3 MB | 10.6 MB |

Small-file parsing, in microseconds per parse:

| Implementation | 128 entries |
|---|---:|
| adotenv parse | 42.3 us |
| adotenv parse + values | 54.3 us |
| adotenv parse + map | 50.3 us |
| dotenvy iterator + map | 85.0 us |
| dotenv-compat parse | 59.0 us |
| dotenv-ng input-only | 74.4 us |
| dotenv-parser map | 215.3 us |

### Loader profiles

Per load on the 65,536-entry fixture:

| Profile | Wall time | Instructions | Peak RSS | Retained RSS |
|---|---:|---:|---:|---:|
| values-only load | 46.9 ms | 364M | 11.2 MB | 10.1 MB |
| default load | 93.9 ms | 502M | 47.7 MB | 28.0 MB |
| full-report load | 135.8 ms | 683M | 57.2 MB | 37.9 MB |

### Parse-only binaries

| Binary | Stripped size |
|---|---:|
| adotenv | 446 KB |
| dotenv_compat | 367 KB |
| dotenv_ng | 404 KB |
| dotenv_parser | 449 KB |
| dotenvy | 386 KB |

<!-- END GENERATED BENCHMARKS -->

Wall time varies with host load. Instruction counts are the stable CPU metric.
adotenv parse uses fewer instructions than every measured alternative. Its
parse-plus-map path uses more instructions than dotenv-compat and fewer than
dotenvy. adotenv also retains more document memory because it keeps spans, items
and diagnostics. The values-only projection path is the correct comparison for
applications that do not need provenance.

### Footprint

| Crate | Required normal dependencies | MSRV |
|---|---:|---:|
| adotenv | 0 | 1.81 |
| dotenvy | 0 | 1.56 |
| dotenv | 0 | not declared |
| dotenv-compat | 4 | 1.85 |
| dotenv-ng-core | 0 | 1.74 |
| dotenv-parser | 2 | not declared |

adotenv has no required runtime dependencies and supports `no_std` with `alloc`.
Its parse-only binary is within about 22 percent of the smallest measured binary.

## Capability matrix

| Capability | adotenv | dotenvy | dotenv | dotenv-compat | dotenv-ng | dotenv-parser |
|---|---|---|---|---|---|---|
| Literal parse | Yes | Yes | Yes | Yes | Yes | Yes |
| Map or iterator API | Both | Iterator | Loader | Map | Map | Map |
| Lossless source | Yes | No | No | No | No | No |
| Token spans and positions | Yes | No | No | No | No | No |
| Recovery diagnostics | Yes | Limited | No | Limited | Errors | Errors |
| Multiple syntax presets | 5 | 1 | 1 | Node | 1 | 1 |
| Verified edits and formatting | Yes | No | No | No | No | No |
| Sort, compare and examples | Yes | No | No | No | No | No |
| Reference inspection | Yes | No | No | No | No | No |
| Explicit resolution | Yes | No | No | No | Substitution | No |
| Cascade loading and provenance | Yes | Search/load | Search/load | Files | Multiple files | No |
| Values-only projection | Yes | No | No | No | No | No |
| Serde | Yes | No | No | No | No | No |
| CLI | Yes | No | No | No | No | No |
| `no_std` | Yes | No | No | No | No | No |

`dotenv-linter` is a separate CLI category. It provides lint rules and fixes but
does not expose adotenv's library model or loader provenance.

## Correctness

adotenv has a pinned conformance corpus for Node, Python, Compose and Docker
behavior. It also has parser, edit, encoding, resolution and formatting fuzz
targets.

The main gap is breadth, not absence. Add more pinned symbols and differential
checks against Node and Python, especially for malformed and multiline cases.
Keep every observation tied to a source identity and input hash.

## Documentation

adotenv has 20 public documents covering architecture, dialects, edits,
formatting, resolution, loading, serde, CLI, integrations, quality and
performance. Examples in the README are doctested.

Gaps:

- no dedicated documentation site;
- no guided tutorial or task-based examples;
- design examples are not compiled;
- no searchable API-to-task index;
- no published benchmark dashboard;
- `adotenv.github.io` is unavailable because there is no `adotenv` GitHub
  organization.

A project site can use `asamarts.github.io/adotenv` now, or a custom domain, or
an `adotenv` organization if that name can be created.

## API assessment

Strengths:

- one parse result supports inspection, edits, comparison and formatting;
- policy is explicit and composable;
- errors and diagnostics are structured;
- loading and process mutation stay opt-in;
- values, origins and reports are borrowed views.

Risks:

- the public surface is broad for new users;
- similar concepts use several types (`Document`, `Entry`, `Item`, views,
  `LoadedEnvironment`, `ResolvedEnvironment`);
- examples are spread across the README and design docs;
- the migration from parse to edit to load is not presented as a single guided
  path.

The next step is a task-based API audit, not a redesign.

## Priorities

1. Commit a reproducible comparison harness and keep these numbers current.
2. Build a documentation site with a tutorial, task guides and search.
3. Improve values-only performance and memory measurements against the same
   fixture.
4. Expand conformance and differential tests.
5. Audit common-task APIs and consolidate examples.
6. Close feature gaps only where they fit the literal, explicit design. File
   encryption, implicit environment search and ambient command execution are not
   automatic goals.
7. Complete the 1.0 evidence for fuzzing and external adoption.