import { LinkButton, Tabs, TabItem } from '@astrojs/starlight/components';
import DocsInstallEvents from '../../../components/DocsInstallEvents.astro';

At the end of this page you have two files: a faithful `Book1.pdf`, and the
`report.json` beside it that names every feature Rendlio approximated or could not
render. Those two artefacts come out of every Rendlio run — the document, and the
account of how it was produced.

:::note[Pre-launch]
Rendlio is pre-launch. The install channels below (`Rendlio.Tool` on NuGet, the
container image, self-contained archives) publish at the public launch; this page
documents the normative CLI contract they ship with. Until then you can
[request a 30-day trial](/trial) to be notified, or follow progress on the
[changelog](/changelog).
:::

## Install

<Tabs syncKey="install">
<TabItem label="dotnet tool">

<div data-install-os="auto">

```bash wrap
dotnet tool install -g Rendlio.Tool
```

</div>

Requires the .NET 10 SDK — [install it from dotnet.microsoft.com](https://dotnet.microsoft.com/download/dotnet/10.0).

</TabItem>
<TabItem label="Docker">

<div data-install-os="docker">

```bash wrap
docker pull ghcr.io/rendlio/rendlio
```

</div>

No local .NET needed — the image is self-contained and runs on x64 and ARM64.

</TabItem>
</Tabs>

<DocsInstallEvents />

Neither .NET nor Docker on the host? The same `rendlio` binary also ships as a
self-contained archive for win-x64, linux-x64, linux-arm64, and osx-arm64.
The [Install](/docs/install) page covers all three channels in full, including how to
verify a release before you run it.

{/* FS-17 §3 route table — /docs/quickstart's CTA is "Download the CLI" → /downloads.
    Starlight pages don't render Base.astro's footer, so without this button the docs
    entry path (nav → /docs → Quickstart) has no route to the archives at all. */}
<LinkButton href="/downloads" icon="cloud-download">Download the CLI</LinkButton>

## Get a licence

[Mint a 30-day trial licence](/trial) — it arrives as a small signed file named
`Rendlio.license`. Save it in the directory you convert from, or once in
`~/.rendlio/`, and the engine finds it by itself; `--license <path>` overrides both.
Without a licence Rendlio still converts with every feature, but the output carries
a diagonal evaluation watermark and warning `W9001`.

Verification is entirely offline — a signature check against keys embedded in the
binary. **The engine never phones home**, on any tier. The full resolution order,
the tier table, and the free Community tier are in the
[licensing guide](/docs/licensing).

## Convert

Both paths take the same flags: `-o` / `--output` is the output path, and the
format comes from `--format` (default `pdf`) — never from the file extension.
`--report` writes the compatibility report.

<Tabs syncKey="install">
<TabItem label="dotnet tool">

With `Rendlio.license` saved next to it:

```bash wrap
rendlio convert Book1.xlsx -o Book1.pdf --report report.json
```

</TabItem>
<TabItem label="Docker">

Mount the working directory, and pass the licence from inside it:

```bash wrap
docker run --rm -v "$PWD:/work" ghcr.io/rendlio/rendlio convert /work/Book1.xlsx -o /work/Book1.pdf --report /work/report.json --license /work/Rendlio.license
```

</TabItem>
</Tabs>

## Read the report

`report.json` is the machine-readable account of the run. Two arrays carry the
substance: `features[]` is every deviation from faithful rendering — a convert-mode
report lists deviations only, so an empty array means nothing deviated — and
`warnings[]` is the coded warning list.

```json wrap
{
  "schemaVersion": "1.0",
  "engine": { "name": "Rendlio", "version": "0.3.1", "releaseDate": "2026-10-02" },
  "input": { "fileName": "Book1.xlsx", "sizeBytes": 183422, "sha256": "…64 hex…" },
  "mode": "convert",
  "result": { "status": "unsupported-content", "exitCode": 2 },
  "pages": { "count": 7 },
  "features": [
    {
      "id": "F-CHT-stacked",
      "status": "unsupported",
      "count": 2,
      "locations": [{ "sheet": "Summary", "objectId": "chart2" }],
      "locationsTruncated": false,
      "detail": "Stacked bar charts are not yet rendered (planned post-GA)."
    }
  ],
  "warnings": [
    {
      "code": "W5001",
      "severity": "warn",
      "message": "Default font 'Aptos Narrow' is not available; substituted 'Carlito'. Column widths and line breaks may shift.",
      "location": { "sheet": null, "ref": null, "objectId": null }
    }
  ],
  "timings": { "parseMs": 41, "layoutMs": 118, "renderMs": 96, "totalMs": 262 }
}
```

The exit code is that verdict as a number:

| Code | Meaning |
|---|---|
| 0 | clean |
| 1 | rendered with warnings |
| 2 | unsupported content present |
| 3 | invalid input |
| 4 | resource limit hit |
| 5 | internal error |

Exit code 2 is a feature, not a failure. The document was written and is complete;
what the 2 tells you is that the workbook contained something Rendlio does not yet
render, and `features[]` names it with a location. Nothing is approximated
silently — every deviation is in the report, which is why `2` is a *review this*
signal rather than a broken build. Most pipelines treat `<= 1` as pass and `2` as
review; the full contract per code is on the
[CLI reference](/docs/cli#exit-codes).

## Next steps

- [CLI reference](/docs/cli) — every command, flag, and environment variable, with types and defaults
- [Compatibility report](/docs/compat-report) — the v1 schema, status semantics, and CI gating with `jq`
- [PDF/A-2b and PNG output](/docs/cli/convert#options) — `--format pdfa` for archival PDF, `--format png --dpi 200` for one image per page
- [Deterministic mode](/docs/deployment) — `--deterministic` with `--reference-date` for byte-identical output across runs and hosts