Applications
The contents of this page primarily relate to application components. The term "components" in the Operations API and CLI generally refers to applications specifically. See the Components Overview for a full explanation of terminology.
Harper offers several approaches to managing applications that differ between local development and remote Harper instances.
Local Development
dev and run Commands
Added in: v4.2.0
The quickest way to run an application locally is with the dev command inside the application directory:
harperdb dev .
The dev command watches for file changes and restarts Harper worker threads automatically.
The run command is similar but does not watch for changes. Use run when the main thread needs to be restarted (the dev command does not restart the main thread).
Stop either process with SIGINT (Ctrl+C).
Deploying to a Local Harper Instance
To mimic interaction with a hosted Harper instance locally:
-
Start Harper:
harperdb -
Deploy the application:
harperdb deploy \
project=<name> \
package=<path-to-project> \
restart=true- Omit
targetto deploy to the locally running instance. - Setting
package=<path-to-project>creates a symlink so file changes are picked up automatically between restarts. restart=truerestarts worker threads after deploy. Userestart=rollingfor a rolling restart.
- Omit
-
Use
harperdb restartin another terminal to restart threads at any time. -
Remove an application:
harperdb drop_component project=<name>
Not all component operations are available via CLI. When in doubt, use the Operations API via direct HTTP requests to the local Harper instance.
Example:
harperdb deploy \
project=test-application \
package=/Users/dev/test-application \
restart=true
Use
package=$(pwd)if your current directory is the application directory.
Remote Management
Managing applications on a remote Harper instance uses the same operations as local management. The key difference is specifying a target along with credentials:
harperdb deploy \
project=<name> \
package=<package> \
username=<username> \
password=<password> \
target=<remote> \
restart=true \
replicated=true
Credentials can also be provided via environment variables:
export CLI_TARGET_USERNAME=<username>
export CLI_TARGET_PASSWORD=<password>
harperdb deploy \
project=<name> \
package=<package> \
target=<remote> \
restart=true \
replicated=true
Package Sources
When deploying remotely, the package field can be any valid npm dependency value:
- Omit
packageto package and deploy the current local directory - npm package:
package="@harperdb/status-check" - GitHub:
package="HarperDB/status-check"orpackage="https://github.com/HarperDB/status-check" - Private repo (SSH):
package="git+ssh://git@github.com:HarperDB/secret-app.git" - Tarball:
package="https://example.com/application.tar.gz"
When using git tags, use the semver directive for reliable versioning:
HarperDB/application-template#semver:v1.0.0
Harper generates a package.json from component configurations and uses a form of npm install to resolve them. This is why specifying a local file path creates a symlink (changes are picked up between restarts without redeploying).
For SSH-based private repos, use the Add SSH Key operation to register keys first.
Dependency Management
Harper uses npm and package.json for dependency management.
During application loading, Harper follows this resolution order to determine how to install dependencies:
- If
node_modulesexists, or ifpackage.jsonis absent — skip installation - Check the application's
harperdb-config.yamlforinstall: { command, timeout }fields - Derive the package manager from
package.json#devEngines#packageManager - Default to
npm install
The add_component and deploy_component operations support install_command and install_timeout fields for customizing this behavior.
Example harperdb-config.yaml with Custom Install
myApp:
package: ./my-app
install:
command: yarn install
timeout: 600000 # 10 minutes
Example package.json with devEngines
{
"name": "my-app",
"version": "1.0.0",
"devEngines": {
"packageManager": {
"name": "pnpm",
"onFail": "error"
}
}
}
If you plan to use an alternative package manager, ensure it is installed on the host machine. Harper does not support the
"onFail": "download"option and falls back to"onFail": "error"behavior.
Advanced: Direct harperdb-config.yaml Configuration
Applications can be added to Harper by adding them directly to harperdb-config.yaml (located in the Harper rootPath, typically ~/hdb).
status-check:
package: '@harperdb/status-check'
The entry name does not need to match a package.json dependency. Harper transforms these entries into a package.json and runs npm install.
Any valid npm dependency specifier works:
myGithubComponent:
package: HarperDB-Add-Ons/package#v2.2.0
myNPMComponent:
package: harperdb
myTarBall:
package: /Users/harper/cool-component.tar
myLocal:
package: /Users/harper/local
myWebsite:
package: https://harperdb-component
Harper generates a package.json and installs all components into <componentsRoot> (default: ~/hdb/components). A symlink back to <rootPath>/node_modules is created for dependency resolution.
Use
harperdb get_configurationto find therootPathandcomponentsRootvalues on your instance.
Operations API
Component operations are restricted to super_user roles.
add_component
Creates a new component project in the component root directory using a template.
project(required) — Name of the project to createtemplate(optional) — Git URL of a template repository. Defaults tohttps://github.com/HarperFast/application-templateinstall_command(optional) — Install command. Defaults tonpm installinstall_timeout(optional) — Install timeout in milliseconds. Defaults to300000(5 minutes)replicated(optional) — Replicate to all cluster nodes
{
"operation": "add_component",
"project": "my-component"
}
deploy_component
Deploys a component using a package reference or a base64-encoded .tar payload.
project(required) — Name of the projectpackage(optional) — Any valid npm reference (GitHub, npm, tarball, local path, URL)payload(optional) — Base64-encoded.tarfile contentforce(optional) — Allow deploying over protected core components. Defaults tofalserestart(optional) —truefor immediate restart,'rolling'for sequential cluster restartreplicated(optional) — Replicate to all cluster nodesinstall_command(optional) — Install command overrideinstall_timeout(optional) — Install timeout override in milliseconds
{
"operation": "deploy_component",
"project": "my-component",
"package": "HarperDB/application-template#semver:v1.0.0",
"replicated": true,
"restart": "rolling"
}
drop_component
Deletes a component project or a specific file within it.
project(required) — Project namefile(optional) — Path relative to project folder. If omitted, deletes the entire projectreplicated(optional) — Replicate deletion to all cluster nodesrestart(optional) — Restart Harper after dropping
{
"operation": "drop_component",
"project": "my-component"
}
package_component
Packages a project folder as a base64-encoded .tar string.
project(required) — Project nameskip_node_modules(optional) — Excludenode_modulesfrom the package
{
"operation": "package_component",
"project": "my-component",
"skip_node_modules": true
}
get_components
Returns all local component files, folders, and configuration from harperdb-config.yaml.
{
"operation": "get_components"
}
get_component_file
Returns the contents of a file within a component project.
project(required) — Project namefile(required) — Path relative to project folderencoding(optional) — File encoding. Defaults toutf8
{
"operation": "get_component_file",
"project": "my-component",
"file": "resources.js"
}
set_component_file
Creates or updates a file within a component project.
project(required) — Project namefile(required) — Path relative to project folderpayload(required) — File content to writeencoding(optional) — File encoding. Defaults toutf8replicated(optional) — Replicate update to all cluster nodes
{
"operation": "set_component_file",
"project": "my-component",
"file": "test.js",
"payload": "console.log('hello world')"
}
SSH Key Management
For deploying from private repositories, SSH keys must be registered on the Harper instance.
add_ssh_key
name(required) — Key namekey(required) — Private key contents (must be ed25519; use\nfor line breaks with trailing\n)host(required) — Host alias for SSH config (used inpackageURL)hostname(required) — Actual domain (e.g.,github.com)known_hosts(optional) — Public SSH keys of the host. Auto-retrieved forgithub.comreplicated(optional) — Replicate to all cluster nodes
{
"operation": "add_ssh_key",
"name": "my-key",
"key": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----\n",
"host": "my-key.github.com",
"hostname": "github.com"
}
After adding a key, use the configured host in deploy package URLs:
"package": "git+ssh://git@my-key.github.com:my-org/my-repo.git#semver:v1.0.0"
Additional SSH key operations: update_ssh_key, delete_ssh_key, list_ssh_keys, set_ssh_known_hosts, get_ssh_known_hosts.