Posted by

Local Development with the HubSpot CLI: Edit in Your Editor, Sync to the Design Manager

Editing templates and modules in the Design Manager works, but it has no Git history, no real code review and a limited editor. The HubSpot CLI (hs) lets you develop in your own editor, keep everything in a Git repository, and sync changes to your HubSpot account. This guide covers the setup and the three commands you will use most.

1. Install the CLI

The CLI is a Node.js package. Install it globally and check that it runs:

npm install -g @hubspot/cli
hs --version
hs --help

Command names have been reorganised over time (for example, many commands now live under hs cms or hs account, with the older short forms kept as aliases). Run hs --help to see exactly what your installed version offers.

2. Authenticate

Run the init command from your project folder:

hs init

It guides you through creating a personal access key in your HubSpot account and stores it in a config file (hubspot.config.yml). You can later add more accounts, such as a sandbox, with hs auth and list them with hs accounts list (or hs account list in newer versions).

Do not commit this file. It contains a credential. Add it to .gitignore straight away:

# .gitignore
hubspot.config.yml
node_modules/

3. Create something to work on

You can scaffold a module locally:

hs create module my-banner

This creates a my-banner.module folder with module.html, fields.json, meta.json and optional CSS and JS files. If you already have a theme in your account, pull it down instead (next section).

4. The three commands that matter

fetch: download from HubSpot

hs fetch my-theme ./my-theme

The first argument is the path in the Design Manager, the second is the local destination. Use it once to start a local copy of an existing theme.

upload: push local files to HubSpot

hs upload ./my-theme my-theme

The first argument is the local source, the second is the destination path in the Design Manager. Use it for a one-off deploy, for example from a CI job.

watch: upload on every save

hs watch ./my-theme my-theme

Leave this running while you work. Each time you save a file, it is uploaded, so you can refresh the page preview and see the result. The command has options such as --initial-upload (upload everything when it starts) and --remove (delete files in HubSpot when you delete them locally). Be careful with --remove: check the destination path first, because it deletes remote files.

A simple team workflow

  1. Fetch the theme once, commit it to Git as the baseline.
  2. Create a branch per change and run hs watch against a sandbox or test account, not production.
  3. Review the change in a pull request.
  4. After merge, run hs upload against production, ideally from CI with a key stored as a secret.

Treat Git as the source of truth. If someone edits a file directly in the Design Manager, fetch before you upload so you do not overwrite their change.

Common problems

  • Wrong account: if you have several accounts configured, set a default or pass --account so you do not upload to the wrong portal.
  • Files appear under the wrong folder: double-check which argument is the local path and which is the HubSpot path. The local path always comes first for upload and watch.
  • Authentication errors: the personal access key may have been revoked or lack the CMS scopes. Create a new key and re-run hs auth.

Wrap-up

With fetch, watch and upload you get a normal development loop: your editor, Git history, code review and safe testing in a sandbox. Start by fetching one small theme, putting it in a repository, and watching it against a test account.

Sources

  • HubSpot Developer Docs: Local development tools / HubSpot CLI (developers.hubspot.com)
  • HubSpot Developer Docs: CMS CLI commands reference (developers.hubspot.com)