Twenty defines your CRM schema as code
Open-source CRM positioned as an alternative to Salesforce, letting technical teams define objects, fields, and views as code on NestJS, PostgreSQL, and GraphQL.
At a glance
- What is it?
- An open-source CRM positioned as the alternative to Salesforce, where objects, fields and views are defined in TypeScript and published to a workspace. The monorepo is Yarn-only on Node 26.5.1 or newer, carries a block of transitive version pins, and its agent-skills install command points at a branch that is created by the first successful publish from main.
- Who is it for?
- Adopt Twenty when your team wants its CRM schema under version control and is willing to run the stack, because objects, fields and views as code is a real difference from a click-together CRM and the manifest is honest about what the build demands. Check how existing data gets in before adopting: the installation section describes no import, export or migration step, so confirm that in the docs.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- twentyhq/twenty60,926 ★ · +7,153
| Repository | 2026-07-28 | 2026-11-14 |
|---|---|---|
| twentyhq/twenty | 53.8k | 60.9k |
7,153 Stars in the last 109 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The skills install points at a branch that does not exist yet
The most telling limitation here is a sentence admitting a branch has not been created. The documented way to install the official Twenty app skills for a coding agent is one command pointing at the agent-skills branch of this repository, and the text then states that the branch is created by the first successful publish from main, and that until then you should follow the local build instructions. So until that publish has happened the headline install for agent harnesses does not resolve, and the documented workaround is the local build instructions. That is a bootstrap ordering problem rather than a defect, but it has a real cost: anyone evaluating the agent tooling has to follow the local build instructions first.
npx skills add https://github.com/twentyhq/twenty/tree/agent-skills --listA separate SKILLS.md file at the repository root is said to explain the other skill families and who each is for.
The manifest refuses npm and pins Node 24.5
The root package manifest is unusually prescriptive about its toolchain, and it says so in the engines field. Node is a caret range on 26.5.1, Yarn is 4.0.2 or newer, and the npm entry is not a version at all but the literal string please-use-yarn. A packageManager field pins yarn at 4.18.1, and a .nvmrc sits at the top of the tree. The consequence is that this monorepo is Yarn-only by declaration rather than by preference, and an npm or pnpm install is turned away instead of quietly working. That matters most for CI and for new contributors, whose first instinct on a TypeScript repository is npm.
About two dozen transitive pins live in a single resolutions block
Look past the direct dependencies and the resolutions field is where much of the maintenance cost sits. In the visible part of the manifest it pins nested dependencies such as zapier-platform-core's form-data to 4.0.6, the undici used by nx and miniflare to 7.30.1, the esbuild used by lingui's CLI and zapier-platform-cli to 0.28.1, and also chokidar, tmp and yeoman-environment. A "//resolutions" comment explains that each entry forces a version outside some parent's declared range because no parent release carries the fix, or keeps a single copy of a package for type identity, and should be removed once its drop condition is met; the form-data pin is tied to CVE-2026-12143, a CRLF injection advisory. The consequence is that each of these pins is an entry that has to be revisited when its parent package catches up.
Two release trains cut on the same day, sharing a minor number
The three most recent releases were all published on 2026-10-30, and they are not three versions of one thing. One is an SDK release, sdk/v2.54.0, and two are releases of the main application, twenty/v2.54.0 and twenty/v2.53.1, each under its own tag prefix. The SDK and the application are therefore tagged separately while sharing version numbers, so the bare string 2.54.0 is ambiguous and only becomes meaningful with the prefix in front of it. The SDK and application 2.54.0 tags were cut within seconds of each other, which points to a coordinated release, but the tag list does not record which SDK release belongs with which application release.
The cloud path trades version control for always being current
Two installation routes are offered and they are opposites. The cloud route is a signup, and the description of the result is worth reading closely: a workspace in under a minute, with no infrastructure to manage and always up to date. The self-hosting route is Docker Compose, or a local setup from a guide, and it means running the stack yourself, which given the declared stack means TypeScript services on NestJS with BullMQ for queues, alongside PostgreSQL and Redis, behind a React front end. The phrase always up to date is the entire trade. You avoid maintenance and you give up version pinning, and your schema sits on infrastructure whose upgrade cadence you do not control. That is a reasonable default for a team wanting a CRM this week and a poor one for a team that needs to know what changed last Tuesday, which is also the team the rest of this repository is written for.
The schema is code, and the migration story is the part left out
The pitch is that objects, fields and views are defined in code rather than assembled by clicking, and the example is short enough to read in full. An object declares a singular and a plural name, singular and plural labels, and a fields array where each field carries a name, a label and a type drawn from an enum, with text, currency and date-time used in the sample. You scaffold a new app with a create command, then ship it to your workspace with a publish command that takes a private flag, and the development guide is said to cover objects, views, agents and logic functions. What none of that covers is the path from a workspace that already holds data to one built this way. The installation section does not describe an import, export or migration step, so for a team replacing an existing CRM it is worth confirming in the docs how existing data gets in.
GitHub cannot classify the licence, and the manifest says AGPL-3.0
Check the licence the way most people check it, on the repository page, and this project comes back unclassified: the platform's own licence detection did not identify one. The authoritative statement sits one level down, in the root package manifest, which declares AGPL-3.0, and a LICENSE file is present at the top of the tree. So the file to read is the manifest rather than the badge, and the discrepancy is worth knowing before anyone builds a compliance story on the repository page. The practical consequence for an adopting team is small but real, because an unclassified repository is the sort of thing a procurement check flags, and the answer it turns out to be, AGPL-3.0, carries its own obligations for software delivered as a network service.
Editorial conclusion
Adopt Twenty when your team wants its CRM schema under version control and is willing to run the stack, because objects, fields and views as code is a real difference from a click-together CRM and the manifest is honest about what the build demands. Check how existing data gets in before adopting: the installation section describes no import, export or migration step, so confirm that in the docs. Three things to settle first. The toolchain is Yarn-only on Node 26.5.1 or newer, with npm set to please-use-yarn. The agent-skills install cannot work until the first successful publish from main, so plan a local build. And read the licence from the package manifest rather than the repository badge, because the platform did not classify it while the manifest declares AGPL-3.0.
Frequently asked questions
How do I use Twenty as a CRM?
It is an open-source CRM you extend with code. You scaffold an app, define objects, fields and views as code, and publish it to your workspace. The building blocks it names are objects, views, workflows and agents, and a cloud option is offered for teams that do not want to run infrastructure at all.
How do I install Twenty?
There are three routes: sign up for the cloud, scaffold an app with the Twenty CLI (npm install -g twenty, then twenty app init), or self-host with Docker Compose. Note the toolchain requirement, since the manifest declares Node ^26.5.1, Yarn 4.0.2 or newer, and sets the npm entry to please-use-yarn.
Can I extend Twenty with a coding agent?
Yes, through the official app skills, which are said to work in Claude Code, Codex, Cursor, Pi and any other harness supported by the skills CLI. The install command points at an agent-skills branch created by the first successful publish from main, so until that publish happens you have to build the skills locally first.
What licence does Twenty use?
The root package manifest declares AGPL-3.0 and a LICENSE file sits at the repository root, but the platform's own licence detection did not classify the project. Read the manifest rather than the repository page, since AGPL-3.0 carries obligations for software delivered as a network service.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/twentyhq-twenty)Star history chart for your README
[](https://hysenlabs.com/projects/twentyhq-twenty)Was this useful?