Public assets (public/ folder)
The public/ folder at the root of your app holds static files — images, icons, fonts, or any other assets your app needs at runtime. These files are automatically included in builds, synced during dev mode, and uploaded to the server.
Files placed in public/ are:
- Publicly accessible — once synced to the server, assets are served at a public URL. No authentication is needed to access them.
- Available in front components — use asset URLs to display images, icons, or any media inside your React components.
- Available in logic functions — reference asset URLs in emails, API responses, or any server-side logic.
- Used for marketplace metadata — the
logoUrlandscreenshotsfields indefineApplication()reference files from this folder (e.g.,public/logo.png). These are displayed in the marketplace when your app is published. - Auto-synced in dev mode — when you add, update, or delete a file in
public/, it is synced to the server automatically. No restart needed. - Included in builds —
yarn twenty buildbundles all public assets into the distribution output.
Accessing public assets with getPublicAssetUrl
Use the getPublicAssetUrl helper from twenty-sdk to get the full URL of a file in your public/ directory. It works in both logic functions and front components.
In a logic function:
src/logic-functions/send-invoice.ts
src/front-components/company-card.tsx
path argument is relative to your app’s public/ folder. Both getPublicAssetUrl('logo.png') and getPublicAssetUrl('public/logo.png') resolve to the same URL — the public/ prefix is stripped automatically if present.
Using npm packages
You can install and use any npm package in your app. Both logic functions and front components are bundled with esbuild, which inlines all dependencies into the output — nonode_modules are needed at runtime.
Installing a package
src/logic-functions/fetch-data.ts
src/front-components/chart.tsx
How bundling works
The build step uses esbuild to produce a single self-contained file per logic function and per front component. All imported packages are inlined into the bundle. Logic functions run in a Node.js environment. Node built-in modules (fs, path, crypto, http, etc.) are available and do not need to be installed.
Front components run in a Web Worker. Node built-in modules are not available — only browser APIs and npm packages that work in a browser environment.
Both environments have twenty-client-sdk/core and twenty-client-sdk/metadata available as pre-provided modules — these are not bundled but resolved at runtime by the server.
Testing your app
The SDK provides programmatic APIs that let you build, deploy, install, and uninstall your app from test code. Combined with Vitest and the typed API clients, you can write integration tests that verify your app works end-to-end against a real Clara server.Setup
The scaffolded app already includes Vitest. If you set it up manually, install the dependencies:vitest.config.ts at the root of your app:
vitest.config.ts
src/__tests__/setup-test.ts
Programmatic SDK APIs
Thetwenty-sdk/cli subpath exports functions you can call directly from test code:
| Function | Description |
|---|---|
appBuild | Build the app and optionally pack a tarball |
appDeploy | Upload a tarball to the server |
appInstall | Install the app on the active workspace |
appUninstall | Uninstall the app from the active workspace |
success: boolean and either data or error.
Writing an integration test
Here is a full example that builds, deploys, and installs the app, then verifies it appears in the workspace:src/__tests__/app-install.integration-test.ts
Running tests
Make sure your local Clara server is running, then:Type checking
You can also run type checking on your app without running tests:tsc --noEmit and reports any type errors.
CLI reference
Beyonddev, build, add, and typecheck, the CLI provides commands for executing functions, viewing logs, and managing app installations.
Executing functions (yarn twenty exec)
Run a logic function manually without triggering it via HTTP, cron, or database event:
Viewing function logs (yarn twenty logs)
Stream execution logs for your app’s logic functions:
This is different from
yarn twenty server logs, which shows the Docker container logs. yarn twenty logs shows your app’s function execution logs from the Clara server.Uninstalling an app (yarn twenty uninstall)
Remove your app from the active workspace:
Managing remotes
A remote is a Clara server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.~/.twenty/config.json.
CI with GitHub Actions
The scaffolder generates a ready-to-use GitHub Actions workflow at.github/workflows/ci.yml. It runs your integration tests automatically on every push to main and on pull requests.
The workflow:
- Checks out your code
- Spins up a temporary Clara server using the
getclaratech/clara/.github/actions/spawn-twenty-docker-imageaction - Installs dependencies with
yarn install --immutable - Runs
yarn testwithTWENTY_API_URLandTWENTY_API_KEYinjected from the action outputs
.github/workflows/ci.yml
spawn-twenty-docker-image action starts an ephemeral Clara server directly in the runner and outputs the connection details. The GITHUB_TOKEN secret is provided automatically by GitHub.
To pin a specific Clara version instead of latest, change the TWENTY_VERSION environment variable at the top of the workflow.