> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lodemc.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Keys, trust and publishing

> Keys, trusted and untrusted, packing a .nxe

## The key

Every expansion carries an `apiKey` in `meta.json`: a secret created on NMCrate and bound to one expansion id. The app verifies it each time the expansion loads, including after every hot reload.

<Warning>
  An expansion whose key does not check out does not run at all.
</Warning>

## Verified and untrusted

| Situation                                                                      | Result                                |
| ------------------------------------------------------------------------------ | ------------------------------------- |
| The expansion is published on NMCrate and the key matches it                   | Loads normally                        |
| The key is active and bound to this id, but the expansion is not published yet | **Loads, marked Untrusted**           |
| The key is unknown, disabled, or bound to a different expansion                | Does not load; the message says which |

**Untrusted** is the normal state while you are building something: nobody has reviewed it, and the Expansions page says so. It behaves exactly like a verified expansion otherwise.

For the app to tell "not published yet" apart from "disabled or someone else's key", it asks NMCrate's secrets service, which needs `SECRETS_API_KEY` in the app's `.env`. Without it, unpublished expansions do not load and the message says so. That is a setting for whoever builds the app, not for you.

## Offline

Verification is a network call, so an expansion does not load while the app is offline. This applies to legacy `main.js` expansions too.

## Packing a .nxe

`.nxe` is the packaged form NMCrate distributes: your folder, compressed and encrypted.

In the app, the pack action (`window.nexomaker.compileNxe()`) writes `Expansions/Exports/<folder>.nxe` for every expansion folder you have. For an SDK expansion it packs only if:

* `meta.json` and `config.json` are valid, and
* every module builds, with every import resolving.

So a `.nxe` that exists is one that at least loads. `node_modules` is left out, since it is only your editor's types.

The problems that stopped a pack are listed in the app's log.

## Before you publish

* `id` matches the NMCrate expansion the key belongs to, and is not going to change afterwards.
* `version` is bumped; that is what an update compares.
* `permissions` lists only what you actually use. Each one is a line the user reads.
* `sdkVersion` is the range you tested against.
* The expansion loads from a clean copy of the folder, with no leftovers from your editor.

## A note on secrets

<Warning>
  Your key is readable by anyone who has your expansion: in a folder it is plain text, and a `.nxe` is decrypted by the app to read it. Treat it as an identifier, not a password, and never put any other secret in `meta.json` or in your source.
</Warning>
