# `NPM.Install.CI`
[🔗](https://github.com/elixir-volt/npm_ex/blob/v0.7.4/lib/npm/install/ci.ex#L1)

Strict frozen install for CI environments.

Implements `npm ci` behavior — validates lockfile matches package.json
exactly, cleans node_modules, and installs from lockfile only.
No lockfile modifications allowed.

# `validation_error`

```elixir
@type validation_error() ::
  :lockfile_missing
  | :package_json_missing
  | {:missing_dep, String.t()}
  | {:extra_dep, String.t()}
```

# `format_errors`

```elixir
@spec format_errors([validation_error()]) :: String.t()
```

Formats validation errors for display.

# `needs_clean?`

```elixir
@spec needs_clean?(String.t()) :: boolean()
```

Determines if node_modules needs to be cleaned before install.

# `preflight`

```elixir
@spec preflight(String.t()) :: :ok | {:error, [String.t()]}
```

Checks if CI install is possible (all prerequisites met).

# `validate`

```elixir
@spec validate(String.t()) :: :ok | {:error, [validation_error()]}
```

Validates that the lockfile is in sync with package.json.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
