The normal HQL workflow has one tool and, when project metadata is needed, one
manifest: hql.json. Generated JavaScript ecosystem files are implementation
details; do not edit them.
For a script, write a versioned import and run the file:
(import [default as ms] from "npm:ms@2.1.3")
(print (ms "2s"))
hql app.hql
No project, install command, or manifest is required. In an HQL project,
hql add npm:ms@2.1.3 records the dependency in hql.json, installs it, and
updates the HQL-owned hql.lock. hql dev and hql build also install a
missing dependency automatically.
Supported source forms are:
| Form | Meaning |
|---|---|
./local.hql, .ts, or .js | Local mixed-language module |
npm:pkg@version | Versioned npm package |
jsr:@scope/pkg@version | Versioned JSR package |
https://example.com/module.ts | Explicit remote ESM module |
bare pkg@version with hql add | Normalized to an npm dependency |
Versions are required for registry dependencies. HQL never silently publishes
or locks an implicit latest version.
A single mod.hql is enough:
hql publish --dry-run
hql publish
Without hql.json, HQL infers the entry, a scoped name from the current user
and directory, version 0.1.0, and both registries. The dry run performs the
real npm and JSR validations without uploading.
Select one registry when wanted:
hql publish --target npm
hql publish --target jsr
hql publish --target all
Use hql.json only when inference is insufficient—for example, to choose a
public name, version, description, license, multiple exports, or a permanent
registry selection:
{
"kind": "library",
"name": "@example/math",
"version": "1.0.0",
"exports": {
".": "./mod.hql",
"./stats": "./stats.hql"
},
"publish": ["npm", "jsr"]
}
hql init can materialize the inferred values, but it is not required:
hql init . --name @example/math --version 1.0.0
hql publish performs this sequence:
*_test.hql and *.test.hql tests..d.ts declarations into dist/.The npm package has "type": "module", an ESM export map, and declaration
paths. The JSR package is also ESM. Consumers do not install HQL; Node, Bun,
JSR runtimes, bundlers, and browsers consume the generated JavaScript.
Two registries cannot provide one atomic cross-registry transaction. HQL preflights both to avoid preventable partial releases, but a network or service failure during the second upload can still leave the first registry published. Published versions are immutable, so recovery means fixing the external issue and publishing the same still-missing target—not overwriting a version.
Authentication is interactive when supported. Automation may provide
HQL_NPM_TOKEN, HQL_NPM_OTP, and HQL_JSR_TOKEN; HQL never writes these
secrets into the package.
hql pack writes:
dist/
esm/ portable ESM for npm and browsers
jsr/esm/ JSR-oriented ESM
types/ TypeScript declarations
package.json generated npm metadata
jsr.json generated JSR metadata
README.md
LICENSE when the selected license has generated/copied text
These files are publish output, not project configuration. The only source
manifest is hql.json.
An existing JS/TS project may keep its own package.json and package manager.
Running its entry with hql is zero-config:
hql src/main.ts
If that project must keep Vite, esbuild, Rollup, Webpack, or Bun as its command,
install hql-lang in that project and enable the matching adapter. This is the
one unavoidable per-project integration because general-purpose bundlers do not
discover a new source extension from a globally installed executable.