O que são aplicativos?
Os aplicativos permitem criar e gerenciar personalizações do Twenty como código. Em vez de configurar tudo pela UI, você define seu modelo de dados e funções de lógica em código — tornando mais rápido criar, manter e distribuir para vários workspaces. O que você pode fazer hoje:- Defina objetos e campos personalizados como código (modelo de dados gerenciado)
- Crie funções de lógica com gatilhos personalizados
- Implemente o mesmo aplicativo em vários espaços de trabalho
Pré-requisitos
- Node.js 24+ e Yarn 4
- Um espaço de trabalho do Twenty e uma chave de API (crie uma em https://app.twenty.com/settings/api-webhooks)
Primeiros passos
Crie um novo aplicativo usando o gerador oficial, depois autentique-se e comece a desenvolver:Estrutura do projeto (com scaffold)
Ao executarnpx create-twenty-app@latest my-twenty-app, o gerador:
- Copia um aplicativo base mínimo para
my-twenty-app/ - Adiciona uma dependência local
twenty-sdke a configuração do Yarn 4 - Cria arquivos de configuração e scripts conectados à CLI
twenty - Gera uma configuração de aplicativo padrão e um papel padrão para as funções
- package.json: Declares the app name, version, engines (Node 24+, Yarn 4), and adds
twenty-sdkplus atwentyscript that delegates to the localtwentyCLI. Runyarn twenty helpto list all available commands. - .gitignore: Ignora artefatos comuns como
node_modules,.yarn,generated/(cliente tipado),dist/,build/, pastas de cobertura, arquivos de log e arquivos.env*. - yarn.lock, .yarnrc.yml, .yarn/: Bloqueiam e configuram a ferramenta Yarn 4 usada pelo projeto.
- .nvmrc: Fixa a versão do Node.js esperada pelo projeto.
- eslint.config.mjs e tsconfig.json: Fornecem lint e configuração do TypeScript para os fontes TypeScript do seu aplicativo.
- README.md: Um README curto na raiz do aplicativo com instruções básicas.
- public/: Uma pasta para armazenar recursos públicos (imagens, fontes, arquivos estáticos) que serão servidos com sua aplicação. Os arquivos colocados aqui são enviados durante a sincronização e ficam acessíveis em tempo de execução.
- src/: O local principal onde você define seu aplicativo como código
Detecção de entidades
O SDK detecta entidades analisando seus arquivos TypeScript em busca de chamadasexport default define<Entity>({...}). Cada tipo de entidade tem uma função utilitária correspondente exportada de twenty-sdk:
| Função utilitária | Tipo de entidade |
|---|---|
defineObject() | Definições de objetos personalizados |
defineLogicFunction() | Definições de funções de lógica |
defineFrontComponent() | Definições de componentes de front-end |
defineRole() | Definições de papéis |
defineField() | Extensões de campos para objetos existentes |
A nomeação de arquivos é flexível. A detecção de entidades é baseada em AST — o SDK varre seus arquivos fonte em busca do padrão
export default define<Entity>({...}). Você pode organizar seus arquivos e pastas como quiser. Agrupar por tipo de entidade (por exemplo, logic-functions/, roles/) é apenas uma convenção para organização do código, não um requisito.yarn twenty app:generatewill create agenerated/folder (typed Twenty client + workspace types).yarn twenty entity:addwill add entity definition files undersrc/for your custom objects, functions, front components, or roles.
Autenticação
The first time you runyarn twenty auth:login, you’ll be prompted for:
- URL da API (padrão: http://localhost:3000 ou o perfil do seu espaço de trabalho atual)
- Chave de API
~/.twenty/config.json. Você pode manter vários perfis e alternar entre eles.
Gerenciando espaços de trabalho
yarn twenty auth:switch, all subsequent commands will use that workspace by default. Você ainda pode substituí-lo temporariamente com --workspace <name>.
Use os recursos do SDK (tipos e configuração)
O twenty-sdk fornece blocos de construção tipados e funções utilitárias que você usa dentro do seu aplicativo. A seguir estão as partes principais que você usará com mais frequência.Funções utilitárias
O SDK fornece funções utilitárias para definir as entidades do seu app. Conforme descrito em Detecção de entidades, você deve usarexport default define<Entity>({...}) para que suas entidades sejam detectadas:
| Função | Finalidade |
|---|---|
defineApplication() | Configurar metadados do aplicativo (obrigatório, um por app) |
defineObject() | Define objetos personalizados com campos |
defineLogicFunction() | Defina funções de lógica com handlers |
defineFrontComponent() | Definir componentes de front-end para UI personalizada |
defineRole() | Configura permissões de papéis e acesso a objetos |
defineField() | Estender objetos existentes com campos adicionais |
Definindo objetos
Objetos personalizados descrevem tanto o esquema quanto o comportamento de registros no seu espaço de trabalho. UsedefineObject() para definir objetos com validação integrada:
- Use
defineObject()para validação integrada e melhor suporte na IDE. - O
universalIdentifierdeve ser exclusivo e estável entre implantações. - Cada campo requer
name,type,labele seu própriouniversalIdentifierestável. - O array
fieldsé opcional — você pode definir objetos sem campos personalizados. - You can scaffold new objects using
yarn twenty entity:add, which guides you through naming, fields, and relationships.
Os campos base são criados automaticamente. Quando você define um objeto personalizado, o Twenty adiciona automaticamente campos padrão como
name, createdAt, updatedAt, createdBy, position e deletedAt. Você não precisa definir esses no seu array fields — adicione apenas seus campos personalizados.Configuração do aplicativo (application-config.ts)
Todo aplicativo tem um único arquivoapplication-config.ts que descreve:
- O que é o aplicativo: identificadores, nome de exibição e descrição.
- Como suas funções são executadas: qual papel usam para permissões.
- Variáveis (opcional): pares chave–valor expostos às suas funções como variáveis de ambiente.
defineApplication() to define your application configuration:
universalIdentifiersão IDs determinísticos que você controla; gere-os uma vez e mantenha-os estáveis entre sincronizações.applicationVariablestornam-se variáveis de ambiente para suas funções (por exemplo,DEFAULT_RECIPIENT_NAMEfica disponível comoprocess.env.DEFAULT_RECIPIENT_NAME).defaultRoleUniversalIdentifierdeve corresponder ao arquivo do papel (veja abaixo).
Papéis e permissões
Os aplicativos podem definir papéis que encapsulam permissões sobre os objetos e ações do seu espaço de trabalho. O campodefaultRoleUniversalIdentifier em application-config.ts designa o papel padrão usado pelas funções de lógica do seu app.
- A chave de API em tempo de execução, injetada como
TWENTY_API_KEY, é derivada desse papel padrão de função. - O cliente tipado ficará restrito às permissões concedidas a esse papel.
- Siga o princípio do menor privilégio: crie um papel dedicado com apenas as permissões de que suas funções precisam e, em seguida, faça referência ao seu identificador universal.
Papel de função padrão (*.role.ts)
Ao criar um novo aplicativo com o scaffold, a CLI também cria um arquivo de papel padrão. UsedefineRole() para definir papéis com validação integrada:
universalIdentifier desse papel é então referenciado em application-config.ts como defaultRoleUniversalIdentifier. Em outras palavras:
- *.role.ts define o que o papel de função padrão pode fazer.
- application-config.ts aponta para esse papel para que suas funções herdem suas permissões.
- Comece pelo papel gerado pelo scaffold e depois restrinja-o progressivamente seguindo o princípio do menor privilégio.
- Substitua
objectPermissionsefieldPermissionspelos objetos/campos de que suas funções precisam. permissionFlagscontrolam o acesso a recursos em nível de plataforma. Mantenha-os mínimos; adicione apenas o que for necessário.- Veja um exemplo funcional no app Hello World:
packages/twenty-apps/hello-world/src/roles/function-role.ts.
Configuração de função de lógica e ponto de entrada
Cada arquivo de função usadefineLogicFunction() para exportar uma configuração com um handler e gatilhos opcionais.
- route: Expõe sua função em um caminho e método HTTP no endpoint
/s/:
por exemplo,path: '/post-card/create',-> chamar em<APP_URL>/s/post-card/create
- cron: Executa sua função em um agendamento usando uma expressão CRON.
- databaseEvent: Executa em eventos do ciclo de vida de objetos do espaço de trabalho. Quando a operação do evento é
updated, campos específicos a serem observados podem ser especificados no arrayupdatedFields. Se deixar indefinido ou vazio, qualquer atualização acionará a função.
por exemplo, person.updated
Notas:
- O array
triggersé opcional. Funções sem gatilhos podem ser usadas como funções utilitárias chamadas por outras funções. - Você pode misturar vários tipos de gatilho em uma única função.
Payload de gatilho de rota
Quando um gatilho de rota invoca sua função de lógica, ela recebe um objetoRoutePayload que segue o formato do AWS HTTP API v2. Importe o tipo de twenty-sdk:
RoutePayload tem a seguinte estrutura:
| Propriedade | Tipo | Descrição |
|---|---|---|
headers | Record<string, string | undefined> | Cabeçalhos HTTP (apenas aqueles listados em forwardedRequestHeaders) |
queryStringParameters | Record<string, string | undefined> | Parâmetros de query string (valores múltiplos unidos por vírgulas) |
pathParameters | Record<string, string | undefined> | Parâmetros de caminho extraídos do padrão de rota (por exemplo, /users/:id → { id: '123' }) |
corpo | object | null | Corpo da requisição analisado (JSON) |
isBase64Encoded | booleano | Se o corpo está codificado em base64 |
requestContext.http.method | string | Método HTTP (GET, POST, PUT, PATCH, DELETE) |
requestContext.http.path | string | Caminho bruto da requisição |
Encaminhamento de cabeçalhos HTTP
Por padrão, os cabeçalhos HTTP das requisições recebidas não são repassados para sua função de lógica por motivos de segurança. Para acessar cabeçalhos específicos, liste-os explicitamente no arrayforwardedRequestHeaders:
Os nomes dos cabeçalhos são normalizados para minúsculas. Acesse-os usando chaves em minúsculas (por exemplo,
event.headers['content-type']).- Scaffolded: Run
yarn twenty entity:addand choose the option to add a new logic function. Isso gera um arquivo inicial com um handler e configuração. - Manual: Crie um novo arquivo
*.logic-function.tse usedefineLogicFunction(), seguindo o mesmo padrão.
Componentes de front-end
Componentes de front-end permitem criar componentes React personalizados que são renderizados na UI do Twenty. UsedefineFrontComponent() para definir componentes com validação integrada:
- Componentes de front-end são componentes React que renderizam em contextos isolados dentro do Twenty.
- Use o sufixo de arquivo
*.front-component.tsxpara detecção automática. - O campo
componentfaz referência ao seu componente React. - Components are built and synced automatically during
yarn twenty app:dev.
- Scaffolded: Run
yarn twenty entity:addand choose the option to add a new front component. - Manual: Crie um novo arquivo
*.front-component.tsxe usedefineFrontComponent().
Cliente tipado gerado
Runyarn twenty app:generate to create a local typed client in generated/ based on your workspace schema. Use-o em suas funções:
yarn twenty app:generate. Execute novamente após alterar seus objetos ou ao ingressar em um novo workspace.
Credenciais em tempo de execução em funções de lógica
Quando sua função é executada no Twenty, a plataforma injeta credenciais como variáveis de ambiente antes da execução do seu código:TWENTY_API_URL: URL base da API do Twenty que seu aplicativo usa como alvo.TWENTY_API_KEY: Chave de curta duração com escopo para o papel de função padrão do seu aplicativo.
- Você não precisa passar a URL ou a chave de API para o cliente gerado. Ele lê
TWENTY_API_URLeTWENTY_API_KEYde process.env em tempo de execução. - As permissões da chave de API são determinadas pelo papel referenciado no seu
application-config.tsviadefaultRoleUniversalIdentifier. Este é o papel padrão usado pelas funções de lógica do seu app. - Os aplicativos podem definir papéis para seguir o princípio do menor privilégio. Conceda apenas as permissões de que suas funções precisam e, em seguida, aponte
defaultRoleUniversalIdentifierpara o identificador universal desse papel.
Exemplo Hello World
Explore um exemplo mínimo de ponta a ponta que demonstra objetos, funções de lógica, componentes de front-end e vários gatilhos aqui:Configuração manual (sem o gerador)
Embora recomendemos usarcreate-twenty-app para a melhor experiência inicial, você também pode configurar um projeto manualmente. Não instale a CLI globalmente. Instead, add twenty-sdk as a local dependency and wire a single script in your package.json:
twenty script:
yarn twenty <command>, e.g. yarn twenty app:dev, yarn twenty app:generate, yarn twenty help, etc.
Resolução de Problemas
- Authentication errors: run
yarn twenty auth:loginand ensure your API key has the required permissions. - Não é possível conectar ao servidor: verifique a URL da API e se o servidor do Twenty está acessível.
- Types or client missing/outdated: run
yarn twenty app:generate. - Dev mode not syncing: ensure
yarn twenty app:devis running and that changes are not ignored by your environment.