# Kinds of package

A package is Jadpo code shared between apps. There are two kinds, written
in the same format:

| Kind | Contains | Used as |
|---|---|---|
| Provider | One API at one version: resources, operations, types, failures, events and how the API is reached; optionally package actions, subscribers, capability mappings and library functions | A connection: `stripe.payment_intents.create(...)` |
| Library | Types, failures and library functions under `shared/`'s rules: pure, no entities, no routes, no network | `Postcodes.uk.parse(text)`, `Postcodes.UkPostcode` |

A *resource* is a group of an API's operations, such as Stripe's
`payment_intents`. A *library* is a named group of pure functions.

## Which kind a package is

You don't declare the kind: it follows from what is inside. A package
with a `resources/` folder is a provider package, and you need a
connection to call its operations. One without is a library package. A
provider package's library functions can be called without a connection.

## What can be stored

A library package's types may be stored in entity fields and used in a
route's input and output. When an upgrade changes a stored type, the
change shows in the upgrade plan and the migration, as a change to one of
your own types does.

Everything in a provider package follows the provider rules, its library
types included. You may store only ids and plain values from it, and no
provider object or enum type may be part of a route's `Input` or
`Output`. The next version of the API is a new package, so your stored
data and your API must not depend on this one. Keep what you need from a
provider as ids, plain values and built-in types (money, countries, phone
numbers), or as your own types.

## What isn't a package

- **A feature isn't a package.** A whole slice of an app, such as
  invitations or billing, is never installed or copied in as a package.
  Your coding agent writes it from these pages, and the compiler catches
  the dangerous mistakes. Most of what other frameworks take from packages,
  such as sign-in, flags, audit, files and email, is built into Jadpo.
- **A driver isn't a package.** Anything that needs native code, such as a
  new database, a signing scheme or a wire format, comes only in a Jadpo
  release. Packages never carry native or WebAssembly code.

## Built in, or a library package

A thing is built into Jadpo when the compiler gains from knowing it: a
type that turns a mistake into a compile error, carries personal-data
marking, has a SQL or OpenAPI form or generated test values, or is a
security boundary the language should own. Money, countries, currencies,
languages, phone numbers, safe HTML and CSV are built in. Postcodes,
IBAN, VAT numbers, public holidays, repeating dates and QR codes are
packages.

## The golden rule

**A package can do nothing the app can't, and the app can do everything a
package can.** A package is a folder of an app's own code, published.

- Your app's own integrations in `shared/providers/` use the whole package
  format: `provider.jadpo`, `resources/`, `events/`, decoding, `provides/`
  and `runs:`. Its own types, failures, libraries, emails and translations
  live in `shared/` and its domains.
- The compiler treats `packages/` and `shared/providers/` alike. They
  differ only in where the code came from: the lock entry, the digest
  check, being read-only, and the bar a package passes to be published.
- The rule runs one way only. An app can do far more than a package:
  entities, actions over its data, routes, policy and emails.
