---
title: "Installation"
description: "Install @cloudpdf/engine and create a cloud engine pointed at your CloudPDF server."
source: "https://www.cloudpdf.com/docs/engine/getting-started/installation"
---

# Installation

The engine is a single package. Install it in the app that will talk to your
CloudPDF server — typically your frontend, but it also runs in Node.

```sh
pnpm add @cloudpdf/engine@next
```

## Requirements

- **A `@cloudpdf/server` endpoint** — self-hosted or CloudPDF SaaS. The engine
  is a thin HTTP client; it needs a server to talk to.
- **A `fetch` implementation.** All evergreen browsers and Node 18+ ship one
  globally. On older Node you can pass your own (for example `undici`) via the
  `fetch` option.
- **Document-scoped JWTs**, minted by your backend. See
  [Authentication](https://www.cloudpdf.com/docs/engine/getting-started/authentication).

## Create an engine

`createCloudEngine` returns an `Engine` bound to your server's base URL. The
`token` may be a string or a function that returns a fresh token, so you can
rotate credentials without re-creating the engine.

```ts
import { createCloudEngine } from '@cloudpdf/engine';

const engine = createCloudEngine({
  baseUrl: 'https://pdf.your-app.com',
  // String, or a (possibly async) factory called on every request:
  token: async () => fetchTenantToken(),
});
```

### Options

| Option    | Type                                        | Notes                                                                                                                                                    |
| --------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `baseUrl` | `string`                                    | Origin of your `@cloudpdf/server` deployment. A trailing slash is trimmed for you.                                                                       |
| `token`   | `string \| () => string \| Promise<string>` | Optional. Bearer token sent as `Authorization: Bearer …`. Omit it for the public-share flow, where each `open({ kind: 'token' })` carries its own token. |
| `fetch`   | `typeof fetch`                              | Optional. Replace the global `fetch` (e.g. `undici` in Node tests).                                                                                      |

> Prefer a token **factory** over a static string. The engine calls
> it on every request, so short-lived tokens refresh transparently as your
> backend rotates them.

## Verify the install

Open a document by id and read its metadata. If this resolves, your engine,
base URL, and token are wired up correctly.

```ts
const doc = await engine.open({ kind: 'id', id: 'doc_proposal_2026' });
const meta = await doc.metadata.read();

console.log(meta.title);

await doc.close();
```

Next, head to the [Quick start](https://www.cloudpdf.com/docs/engine/getting-started/quick-start) to
render a page.
