- improves `packages/twenty-docs/developers/extend/apps/getting-started.mdx` --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
192 lines
6.6 KiB
Plaintext
192 lines
6.6 KiB
Plaintext
---
|
|
title: Publishing
|
|
description: Distribute your Twenty app to the marketplace or deploy it internally.
|
|
---
|
|
|
|
<Warning>
|
|
Apps are currently in alpha. The feature works but is still evolving.
|
|
</Warning>
|
|
|
|
## Overview
|
|
|
|
Once your app is [built and tested locally](/developers/extend/apps/building), you have two paths for distributing it:
|
|
|
|
- **Deploy a tarball** — upload your app directly to a specific Twenty server for internal or private use.
|
|
- **Publish to npm** — list your app in the Twenty marketplace for any workspace to discover and install.
|
|
|
|
Both paths start from the same **build** step.
|
|
|
|
## Building your app
|
|
|
|
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
|
|
|
```bash filename="Terminal"
|
|
yarn twenty build
|
|
```
|
|
|
|
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
|
|
|
## Deploying to a server (tarball)
|
|
|
|
For apps you don't want publicly available — proprietary tools, enterprise-only integrations, or experimental builds — you can deploy a tarball directly to a Twenty server.
|
|
|
|
### Prerequisites
|
|
|
|
Before deploying, you need a configured remote pointing to the target server. Remotes store the server URL and authentication credentials locally in `~/.twenty/config.json`.
|
|
|
|
Add a remote:
|
|
|
|
```bash filename="Terminal"
|
|
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
|
```
|
|
|
|
### Deploying
|
|
|
|
Build and upload your app to the server in one step:
|
|
|
|
```bash filename="Terminal"
|
|
yarn twenty deploy
|
|
# To deploy to a specific remote:
|
|
# yarn twenty deploy --remote production
|
|
```
|
|
|
|
### Sharing a deployed app
|
|
|
|
Tarball apps are not listed in the public marketplace, so other workspaces on the same server won't discover them by browsing. To share a deployed app:
|
|
|
|
1. Go to **Settings > Applications > Registrations** and open your app
|
|
2. In the **Distribution** tab, click **Copy share link**
|
|
3. Share this link with users on other workspaces — it takes them directly to the app's install page
|
|
|
|
The share link uses the server's base URL (without any workspace subdomain) so it works for any workspace on the server.
|
|
|
|
<Warning>
|
|
Sharing private apps is an Enterprise feature. Go to [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to enable it.
|
|
</Warning>
|
|
|
|
### Version management
|
|
|
|
To release an update:
|
|
|
|
1. Bump the `version` field in your `package.json`
|
|
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
|
3. Workspaces that have the app installed will see the upgrade available in their settings
|
|
|
|
{/* TODO: add screenshot of the Upgrade button */}
|
|
|
|
## Publishing to npm
|
|
|
|
Publishing to npm makes your app discoverable in the Twenty marketplace. Any Twenty workspace can browse, install, and upgrade marketplace apps directly from the UI.
|
|
|
|
### Requirements
|
|
|
|
- An [npm](https://www.npmjs.com) account
|
|
- The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
|
|
|
|
```json filename="package.json"
|
|
{
|
|
"name": "twenty-app-postcard-sender",
|
|
"version": "1.0.0",
|
|
"keywords": ["twenty-app"]
|
|
}
|
|
```
|
|
|
|
### Marketplace metadata
|
|
|
|
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
|
|
|
```ts src/application-config.ts
|
|
export default defineApplication({
|
|
universalIdentifier: '...',
|
|
displayName: 'My App',
|
|
description: 'A great app',
|
|
defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
|
logoUrl: 'public/logo.png',
|
|
screenshots: [
|
|
'public/screenshot-1.png',
|
|
'public/screenshot-2.png',
|
|
],
|
|
});
|
|
```
|
|
|
|
See the [defineApplication accordion](/developers/extend/apps/building#defineentity-functions) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
|
|
|
### Publish
|
|
|
|
```bash filename="Terminal"
|
|
yarn twenty publish
|
|
```
|
|
|
|
To publish under a specific dist-tag (e.g., `beta` or `next`):
|
|
|
|
```bash filename="Terminal"
|
|
yarn twenty publish --tag beta
|
|
```
|
|
|
|
### How marketplace discovery works
|
|
|
|
The Twenty server syncs its marketplace catalog from the npm registry **every hour**.
|
|
|
|
You can trigger the sync immediately instead of waiting:
|
|
|
|
```bash filename="Terminal"
|
|
yarn twenty catalog-sync
|
|
# To target a specific remote:
|
|
# yarn twenty catalog-sync --remote production
|
|
```
|
|
|
|
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
|
|
|
<Note>
|
|
If your app does not define an `aboutDescription` in `defineApplication()`, the marketplace will automatically use your package's `README.md` from npm as the about page content. This means you can maintain a single README for both npm and the Twenty marketplace. If you want a different description in the marketplace, explicitly set `aboutDescription`.
|
|
</Note>
|
|
|
|
### CI publishing
|
|
|
|
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
|
|
|
```yaml filename=".github/workflows/publish.yml"
|
|
name: Publish
|
|
on:
|
|
release:
|
|
types: [published]
|
|
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
|
|
jobs:
|
|
publish:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "24"
|
|
registry-url: https://registry.npmjs.org
|
|
- run: yarn install --immutable
|
|
- run: npx twenty build
|
|
- run: npm publish --provenance --access public
|
|
working-directory: .twenty/output
|
|
```
|
|
|
|
For other CI systems (GitLab CI, CircleCI, etc.), the same three commands apply: `yarn install`, `yarn twenty build`, then `npm publish` from `.twenty/output`.
|
|
|
|
<Note>
|
|
**npm provenance** is optional but recommended. Publishing with `--provenance` adds a trust badge to your npm listing, letting users verify the package was built from a specific commit in a public CI pipeline. See the [npm provenance docs](https://docs.npmjs.com/generating-provenance-statements) for setup instructions.
|
|
</Note>
|
|
|
|
## Installing apps
|
|
|
|
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
|
|
|
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
|
|
|
{/* TODO: add screenshot of the UI when the app is registered */}
|
|
|
|
You can also install apps from the command line:
|
|
|
|
```bash filename="Terminal"
|
|
yarn twenty install
|
|
```
|