Salesforce 5 min read

Eliminating Salesforce XML Fatigue: CLI Schema Scaffolding with Hob

Why manually authoring Salesforce metadata XML kills developer flow, and how Hob brings instantaneous CLI schema scaffolding to custom objects, fields, and metadata.

The transition to modern Salesforce DX and source-driven development was one of the most important evolutionary leaps the ecosystem ever made. Storing configurations in Git, orchestrating ephemeral scratch orgs, and running automated CI/CD pipelines transformed Salesforce from a fragmented ClickOps environment into a disciplined software engineering discipline.

Yet, despite all this modern tooling, a persistent friction point still plagues daily development: Salesforce Metadata XML Fatigue.

When you need to model new domain data locally, you are suddenly thrown into a frustrating dilemma: either endure the slow, context-switching drag of the browser-based Object Manager, or hand-write sprawling, error-prone XML descriptors in your IDE.

To bridge this gap and restore developer flow, we built Hob—an open-source CLI assistant designed to eliminate boilerplate chores and scaffold rock-solid Salesforce schema in milliseconds.

Here is why local schema scaffolding is overdue, and how Hob transforms the way we design Salesforce data models.


The Core Dilemma: ClickOps vs. Raw XML

Whenever an engineer builds a new feature—whether it is a customer onboarding flow, an inventory tracker, or a financial ledger—the foundation begins with the schema: objects, fields, validation constraints, and relationships.

In traditional source-driven workflows, you generally have two paths:

Path A: The Object Manager Roundtrip (The ClickOps Tax)

  1. Run sf org open to launch your browser.
  2. Navigate to Setup → Object Manager.
  3. Click New Custom Object, fill out labels, plural labels, name fields, report settings, and hit Save.
  4. For every single field you need, click New Field, choose the data type radio button, click Next, enter field lengths and decimals, click Next, set Field-Level Security across profiles, click Next, add to page layouts, and click Save.
  5. Alt-tab back to VS Code.
  6. Run sf project retrieve start -m CustomObject:MyObject__c to pull the metadata down to your local repository.
  7. Discover that your retrieval pulled unnecessary profile edits or layout churn, and spend time staging only the schema files in Git.

This loop breaks developer flow. A task that should take 30 seconds of typing turns into five minutes of clicking through web wizards and dealing with Git diff noise.

Path B: Hand-Crafting .field-meta.xml (The XML Rabbit Hole)

Determined to stay inside your terminal and code editor, you decide to create the files manually in force-app/main/default/objects/:

  • You create the folder structure and write My_Object__c.object-meta.xml.
  • You remember to format the <nameField> element correctly with <type>Text</type>.
  • You create a fields/ subdirectory and copy-paste an existing field XML file from another object.
  • You edit the <fullName>, change the <label>, tweak <type>Currency</type>, and adjust <precision> and <scale>.
  • You run sf project deploy start.
  • Deployment fails: You forgot <visibleLines> on a LongTextArea, or you set <deleteConstraint> on an optional Lookup without specifying <referenceTo>, or you missed a closing tag.

The official Salesforce CLI (sf) excels at project creation, org management, and deployments, but historically it has left a void when it comes to fast, opinionated, offline scaffolding for data models.


Enter Hob: The Salesforce House-Elf

In English folklore, a Hob is a benevolent household spirit who works quietly in the dead of night—sweeping the hearth, tidying rooms, and grinding flour before anyone awakens.

Hob brings that exact philosophy to the Salesforce terminal. Built with Node.js and TypeScript, Hob functions as a lightning-fast companion to the Salesforce CLI (sf), taking over repetitive, boilerplate-heavy tasks so developers can stay focused on high-value business logic.

Let’s explore how Hob tackles schema scaffolding.


1. Instant Custom Objects (hob create object)

Creating a new custom object should take one line of shell input.

Instead of writing 20 lines of XML or clicking through six setup screens, you run:

# Basic custom object
hob create object Property

Hob immediately executes the chores:

  • It creates the force-app/main/default/objects/Property__c/ bundle.
  • It writes a compliant Property__c.object-meta.xml metadata descriptor.
  • It derives the human-readable singular label (Property) and uses smart linguistic inflection to compute the plural label (Properties).
  • It automatically appends the requisite __c suffix if omitted.
  • It prepares the fields/ subdirectory so you are ready to start adding attributes immediately.

Need an AutoNumber primary key or custom sharing model? Hob handles that through expressive flags:

# AutoNumber primary key with display format
hob create object Job_Application \
  --name-field-type AutoNumber \
  --auto-number-format "APP-{0000}" \
  --sharing-model Private \
  -d "Tracks applicant progress for open requisitions"

Hob instantly constructs the exact XML Salesforce requires:

<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>Job Application</label>
    <pluralLabel>Job Applications</pluralLabel>
    <description>Tracks applicant progress for open requisitions</description>
    <nameField>
        <displayFormat>APP-{0000}</displayFormat>
        <label>Job Application Number</label>
        <type>AutoNumber</type>
    </nameField>
    <deploymentStatus>Deployed</deploymentStatus>
    <sharingModel>Private</sharingModel>
</CustomObject>

2. Fatigue-Free Field Generation (hob create field)

Adding fields is where XML fatigue hurts the most. A complex data model can easily require 20 to 50 fields. Writing these by hand is tedious; clicking through Object Manager is excruciating.

Hob supports 12+ field types out of the box: Text, Number, Currency, Checkbox, Date, DateTime, Picklist, LongTextArea, Lookup, Percent, Email, Phone, and Url.

Currencies and Numbers

# Currency with custom precision and scale
hob create field Property Price -t Currency --precision 12 --scale 2

Hob populates the correct defaults:

<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Price__c</fullName>
    <label>Price</label>
    <type>Currency</type>
    <required>false</required>
    <precision>12</precision>
    <scale>2</scale>
</CustomField>

Picklists with Zero XML Headaches

Authoring Salesforce picklist XML is notoriously wordy because of nested <valueSet> and <valueSetDefinition> nodes. With Hob, you pass values directly:

hob create field Property Status -t Picklist --values "Draft,Active,Under Contract,Sold"

Hob generates the complete, restricted value set definition:

<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Status__c</fullName>
    <label>Status</label>
    <type>Picklist</type>
    <required>false</required>
    <valueSet>
        <restricted>true</restricted>
        <valueSetDefinition>
            <sorted>false</sorted>
            <value>
                <fullName>Draft</fullName>
                <default>false</default>
                <label>Draft</label>
            </value>
            <value>
                <fullName>Active</fullName>
                <default>false</default>
                <label>Active</label>
            </value>
            <value>
                <fullName>Under Contract</fullName>
                <default>false</default>
                <label>Under Contract</label>
            </value>
            <value>
                <fullName>Sold</fullName>
                <default>false</default>
                <label>Sold</label>
            </value>
        </valueSetDefinition>
    </valueSet>
</CustomField>

Relational Integrity with Lookups

When generating Lookup fields, Hob handles the relationship wiring and automatically applies intelligent deletion constraints:

# Optional Lookup to Account (defaults to SetNull)
hob create field Property Landlord -t Lookup --reference-to Account

# Required Lookup to Contact (automatically enforces Restrict deletion)
hob create field Property Tenant -t Lookup --reference-to Contact -r

3. Custom Metadata Types & Seed Records (hob create cmdt)

Custom Metadata Types (CMDT) are the gold standard for application configuration, feature flags, and business rules because they can be deployed alongside code.

However, setting up a CMDT manually requires creating an __mdt object descriptor, custom fields, and matching records in customMetadata/.

Hob streamlines this entire lifecycle:

# Scaffold the CMDT and an initial starter record in one step
hob create cmdt Tax_Rule -l "Tax Rule" -d "Regional sales tax percentages" --with-record Default_VAT

This single command:

  1. Builds force-app/main/default/objects/Tax_Rule__mdt/Tax_Rule__mdt.object-meta.xml.
  2. Creates the fields/ subdirectory.
  3. Automatically writes a baseline configuration record to force-app/main/default/customMetadata/Tax_Rule.Default_VAT.md-meta.xml.

From there, adding configuration fields uses the exact same field command:

hob create field Tax_Rule__mdt Rate -t Percent --precision 5 --scale 2 -r

4. Complete Permissions in One Step (hob create permset)

Once your schema is in place, you need to grant access so users—and test runners—can interact with it.

Instead of navigating the Permission Set setup UI or manually writing XML arrays, Hob lets you bundle object permissions and Apex class access directly from the command line:

hob create permset Property_Manager \
  -d "Grants full management access to Real Estate objects and services" \
  --objects "Property__c,Account,Contact" \
  --classes "PropertyService,PropertyController"

Hob generates a clean, deployable .permissionset-meta.xml complete with <objectPermissions> (Read, Create, Edit, Delete, ViewAll, ModifyAll) and <classAccesses> for your Apex controllers.


Real-World Speedrun: Modeling an Entire Feature in 45 Seconds

To illustrate the productivity boost, imagine being tasked with building an Equipment Maintenance tracking module.

Watch how fast you can scaffold the entire data layer without touching the mouse or editing a single tag:

# 1. Create the custom object with an AutoNumber key
hob create object Maintenance_Ticket --name-field-type AutoNumber --auto-number-format "TICK-{0000}"

# 2. Add relational links to standard and custom assets
hob create field Maintenance_Ticket Asset -t Lookup --reference-to Asset -r
hob create field Maintenance_Ticket Technician -t Lookup --reference-to Contact

# 3. Add operational status & priority picklists
hob create field Maintenance_Ticket Status -t Picklist --values "New,In Progress,Pending Parts,Closed"
hob create field Maintenance_Ticket Priority -t Picklist --values "Low,Medium,High,Critical"

# 4. Add scheduling dates and estimated costs
hob create field Maintenance_Ticket Scheduled_Date -t Date -r
hob create field Maintenance_Ticket Estimated_Cost -t Currency --precision 10 --scale 2

# 5. Add notes and completion flag
hob create field Maintenance_Ticket Resolution_Notes -t LongTextArea --length 5000
hob create field Maintenance_Ticket Is_Warranty_Covered -t Checkbox --default-value false

# 6. Generate the administrative permission set
hob create permset Maintenance_Admin --objects Maintenance_Ticket__c

# 7. Deploy directly to your active scratch org
hob deploy

In less than a minute, your repository has pristine, version-controlled source files that deploy cleanly on the first pass. No browser lag, no missing XML tags, and zero context switching.


Why Developer Ergonomics Matter

In software engineering, friction compounds. When creating schema feels sluggish, developers cut corners:

  • They delay committing schema changes until the end of the sprint.
  • They reuse ill-fitting existing fields instead of modeling clean entities.
  • They avoid writing Custom Metadata Types because “it’s too annoying to set up the XML.”

Tooling like Hob eliminates this friction. By automating the boilerplate chores that computers are great at, it leaves engineers free to focus on what actually matters: designing clean domain models, writing robust Apex logic, and crafting intuitive user experiences.


Getting Started

Hob is free, open-source, and available on GitHub.

# Clone and build locally
git clone https://github.com/keesjankoster/hob.git
cd hob
npm install
npm run build
npm link

Once linked, run hob --help to explore the full suite of commands—including Apex class generators, trigger frameworks, Test Data Factories, and scratch org lifecycle management.

Let Hob do the chores.

Written by Koster CX

Independent technical consultancy offering web hosting, modern web design, and custom software and Salesforce solutions.

Get in touch

Continue Reading

Related Articles

View all articles →