Blog

We scanned Twenty. The CRM's first mile, mapped.

August 2026 · The Holostaff team · 5 min read

Twenty is the open source CRM built for technical teams: records, objects, fields, and views you shape into whatever your pipeline needs. One command on its repo: holostaff /scan.

The result: 28 routes, 13 components, 21 customer-facing copy strings, 7 coverage gaps, and 7 workflows placed on the customer journey, from Sign up through Onboarding, choosing a plan, browsing records, an AI chat, inviting teammates, and Upgrade plan.

This is the fifth scan in the series, after Documenso, Formbricks, OpnForm, and Atlas CMMS. A CRM is a strange thing to onboard. It is only useful once your data lives in it, and it starts empty. Most of what the map found circles that one fact.

The map, in outline

Seven workflows, each placed at its journey stage, rebuilt here from the scan artifact:

  • Sign upCommit
  • Choose billing planCommit
  • OnboardingOnboard
  • Browse and manage recordsAdopt
  • AI chatAdopt
  • Invite teammates (post-onboarding)Expand
  • Upgrade planExpand

Risk · Browse and manage records

"Empty record list with no obvious next action"

Copilot intervention

"Import a CSV or connect your email to auto-populate your contacts."

Risk · Onboarding

"User unsure about connecting email or OAuth scope feels too aggressive"

Copilot intervention

"Connecting your email imports your contacts automatically. You can always do this later in Settings."

Workflow names, risks, and interventions quoted from the scan artifact, unedited.

The same map on the canvas: all seven workflows, each placed at its journey stage. Rendered from the scan, unedited.

One detail worth pausing on before the findings. The map gave Twenty's AI chat a workflow of its own, at the Adopt stage, with a blank-page stall the scan labeled "User doesn't know what to ask the AI." The copilot line it wrote teaches users to talk to the product's own assistant: "Try asking: 'Show me all deals closing this month' or 'Summarize my last 5 interactions with Acme Corp.'" One AI breaking the ice for another. The map treats the chat like any other feature with an adoption cliff, because it is one.

Finding 1: the empty list is the whole game

Every CRM has the same first-value moment. The record list has your contacts in it, or it has nothing. Twenty's own empty-state code says "Add your first {objectLabel}" and offers "Use our API or add your first {objectLabel} manually." Honest, developer-friendly, and a lot to ask of someone with 400 contacts sitting in a spreadsheet.

The scan flagged the stall on the record index: "Empty record list with no obvious next action." The signal it watches: "Empty state displayed ('Add your first...'); no click within 15s; user navigates away." The copilot line is the one in the card above. Import a CSV or connect your email. One action, and the list stops being empty.

The map flags this moment twice. At the end of Sign up it watches for the user who "lands in workspace but doesn't know what to do next" and answers with "Start by importing your contacts or adding your first company." The scan found the same cliff from two directions, because in a CRM the empty list is the cliff.

The Browse and manage records drill-in: steps down the middle, the empty-list stall and its intervention beside the step they belong to. Rendered from the scan, unedited.

Finding 2: the scan noticed OAuth anxiety

Twenty's onboarding asks you to connect your email early, at /sync/emails, through a Google or Microsoft OAuth screen. That screen asks for your inbox. For plenty of people that is the moment the product stops feeling like a tool and starts feeling like a decision.

The scan wrote the risk in plain words: "User unsure about connecting email or OAuth scope feels too aggressive." It watches for exactly how that hesitation looks in a session: "OAuth modal opened then dismissed; dwell > 45s on sync-emails page without connection; Skip button hover." Hovering over Skip is in the signal. That is what almost-leaving looks like.

The intervention trades pressure for information: "Connecting your email imports your contacts automatically. You can always do this later in Settings." State the benefit, name the exit. Nothing in Twenty's copy says users fear the OAuth screen. The scan inferred it from where the screen sits.

Finding 3: the champion problem, found in the code

On the Upgrade plan workflow, at the Expand stage, the scan flagged a risk that reads like a line from a sales playbook: "Decision-maker isn't the current user; needs internal approval." The signal: "Plan comparison page dwell > 60s; back-button press; return visit within 24h without completing." Someone who keeps coming back to the pricing page without buying is not confused. They are waiting on someone else.

So the intervention is not an in-app nudge. It is an email: "Hi! You were looking at upgrading your Twenty workspace. Here's a summary you can share with your team to make the case." The stated goal, verbatim: "Enable the champion to defend the upgrade internally." The map read routes and billing copy and came back with the oldest truth in B2B software: the person in the product is often not the person with the budget.

The step where the right move is nothing

One risk in the map gets no nudge at all. Profile creation, the first onboarding step, has a stall risk like every other step: the user who pauses without completing. The scan's response is an intervention whose modality is silence, and its content is the reason: "Profile creation is simple and short. Interrupting here would be more annoying than helpful."

A form with two fields does not need a helper. It needs to be left alone. Knowing where users stall and knowing when to stay quiet about it are both things the map has to get right.

Honest limits

Same caveats as every scan in this series. The scan reads code, not production traffic, so its risks are informed hypotheses until rehearsal tests them against simulated users. Twenty is a large monorepo; the scan went deep on the frontend app and recorded 7 coverage gaps in the artifact, including the marketing site, the workflow automation builder, the backend, and the transactional email package. It sampled the 21,000+ line translation file rather than reading all of it. And the map reflects main @ 21a0439f on 2026-08-13, not any fork you might be running.

Five products scanned. Five maps that knew the code.
Yours would be the sixth.

Explore the live Documenso map · or run npm install -g @holostaff/cli on your own repo.