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
- Fetch the theme once, commit it to Git as the baseline.
- Create a branch per change and run
hs watchagainst a sandbox or test account, not production. - Review the change in a pull request.
- After merge, run
hs uploadagainst 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
--accountso 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
uploadandwatch. - 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)
