How I stumbled onto this
I was building a hotel management system and needed a WiFi password field: masked by default, with a reveal toggle. Basically a login-style password input.
There’s no built-in interface for that. input-hash is one-way (you can never read the value back), and the standard input shows the password in plaintext with no toggle. So I was about to scaffold a custom interface extension.
Then I remembered Directus ships a whole set of internal “system” interfaces — the same components that power its own settings screens and system collections. They live here:
https://github.com/directus/directus/tree/main/app/src/interfaces/\_system
Why they’re hidden (and how to use them anyway)
Every one of these is defined with a system: true flag:
export default defineInterface({
id: 'system-input-password',
system: true, // <- this is why it never shows in the interface picker
types: ['string', 'text'],
// ...
});
That flag is the only reason they don’t appear when you’re configuring a field. They’re still registered Vue components like any other interface — so if you set a field’s meta.interface directly to one of their IDs, Directus renders them fine.
You can do it via the API:
PATCH /fields/{collection}/{field}
{
"meta": { "interface": "system-input-password" }
}
…or directly in a directus_fields row / schema snapshot. For the WiFi password, that one line gave me a masked input with a reveal toggle and zero custom code.
The full catalogue (all 29)
I went through every folder in _system on main. They fall into three practical tiers.
Tier 1 — drop-in reusable on any collection. These need no special context and just work on a normal field:
| ID | Field type(s) | What it gives you |
|---|---|---|
system-input-password |
string, text | Masked input with a reveal (eye) toggle — login-style password field. |
system-filter |
json | The full filter / rules builder used across the Data Studio. Store targeting logic, saved filters, campaign conditions. |
system-token |
hash | Generate / regenerate a secret token with reveal + copy. Great for API keys or webhook secrets. |
system-raw-editor |
string, text | Plain raw text editor — no rich-text chrome, just the value. |
system-input-translated-string |
string, text | Text input that accepts $t: translation keys, with a translation picker attached. |
system-folder |
uuid | Pick a folder from the file library. |
system-language |
string | Pick from your configured languages. |
Tier 2 — reusable, but they need a bit of context or an option set. Most of these expect to know which collection they’re operating on (they read it from a sibling field or an option), so they shine on config-style collections:
| ID | Field type(s) | What it gives you |
|---|---|---|
system-collection |
string | Dropdown to pick a single collection. |
system-collections |
json, csv | Multi-select collections. |
system-field |
string | Pick a single field (needs a collection context). |
system-fields |
csv, json | Pick multiple fields (needs collection context). |
system-field-tree |
string | Field picker that traverses relations as a dot-path tree. |
system-display-template |
string | The {{ field }} mustache template builder. Requires a collectionField option naming the sibling field that holds the collection. |
system-display |
string | Pick a display for a field. |
system-display-options |
string | Config options for the chosen display. |
system-interface |
string | Pick an interface. |
system-interface-options |
string | Config options for the chosen interface. |
system-scope |
string | Scope dropdown (used by policies / permissions). |
Tier 3 — system-only. These are technically assignable, but they expect props Directus only injects inside its own settings, so on an arbitrary user field they’ll often render empty or misbehave. Listed for completeness:
| ID | Field type(s) | Purpose |
|---|---|---|
system-collections-translations |
alias | Toggle to enable translations on an item form. |
system-inline-fields |
json | Inline field editor. |
system-license-key |
string | Enterprise license-key input. |
system-manual-flow-select |
string | Select a manual flow to trigger. |
system-mcp-prompts-collection-validation |
alias | Internal validation for the MCP prompts collection (newer AI/MCP feature). |
system-mfa-setup |
text | Two-factor setup (QR + one-time code); tied to user auth. |
system-modules |
json | Configure the module bar. |
system-owner |
string | Shows / points to the owning user. |
system-permissions |
alias | The permissions matrix editor. |
system-theme |
string | Theme picker. |
system-theme-overrides |
json | Theme CSS-variable override editor. |
The two I reach for most
system-input-password— the WiFi field above. Masked + reveal, readable value.system-filter— at a previous company we ran email campaigns and hand-rolled a clunky UI to target users by properties.system-filteris the exact rules builder the Data Studio uses everywhere, storing the result as JSON. It would have saved us days.
Please read this before you ship it
These are internal by design — that’s what the _system prefix and the system: true flag are telling you. They are not part of the public API contract, so IDs, options, and behavior can change between versions without it counting as a breaking change. A few concrete implications:
- Pin and note the version you tested on. I verified all of the above on Directus v11.x.
- Tier 2/3 interfaces may render blank if they can’t find the collection/field context they expect — test each on your actual form, don’t assume.
- Don’t build a client deliverable on Tier 3 without a fallback.
Used with that awareness, Tier 1 in particular is safe enough for real work and saves you writing UI that already ships in the product.
Hope it saves someone an afternoon.