hashgraph / hashgraph/asset-tokenization-studio
npm install fails on a clean clone: prepare hook runs hardhat compile before deps are linked, and HH19 masks an ERR_REQUIRE_ESM from did-jwt → @scure/base@2
- Dominant language
- TypeScript
- Stars
- 33
- Forks
- 28
- Avg merge
- 15h 36m
- Merged PRs (30d)
- 8
Description
A clean clone cannot install. Two separate issues compound, and neither error message points at its cause.
Environment: Node 20.17.0, npm 10.8.2, macOS 15.5 arm64.
## Reproduction
```bash
git clone --depth 1 https://github.com/hashgraph/asset-tokenization-studio
cd asset-tokenization-studio
npm install
```
```
npm error code 1
npm error path .../packages/ats/contracts
npm error command sh -c npx hardhat compile
npm error Error HH19: Your project is an ESM project (you have "type": "module" set in
npm error your package.json) but your Hardhat config file uses the .js extension.
npm error
npm error Rename the file to use the .cjs to fix this problem.
```
`node_modules` is left empty.
## Problem 1 — HH19 is misleading and sends you the wrong way
Both conditions the error asserts are false for this repo:
- `packages/ats/contracts/package.json` has `"type": "commonjs"`, not `"module"`
- the config is `hardhat.config.ts` — there is no `.js` config anywhere in the repo
So following the instruction (rename to `.cjs`) cannot help. The real cause only surfaces with `--show-stack-traces`:
```
Caused by: Error [ERR_REQUIRE_ESM]: require() of ES Module
node_modules/did-jwt/node_modules/@scure/base/index.js
from node_modules/did-jwt/lib/index.cjs not supported.
```
`did-jwt@8.0.18` depends on `@scure/base@^2.0.0`, which is ESM-only, and requires it from a CommonJS entry point. Hardhat catches that while loading the config and re-reports it as HH19.
Dependency path:
```
@hashgraph/asset-tokenization-contracts
└─ @terminal3/ecdsa_vc@0.1.30
└─ @terminal3/vc_core@0.0.33
└─ did-jwt@8.0.18
└─ @scure/base@^2.0.0 ← ESM-only, required from CJS
```
**Workaround:** pin `@scure/base` to `1.2.6` via a root `overrides` entry. `overrides` alone was not sufficient here — npm still left a nested `did-jwt/node_modules/@scure/base@2.0.0` that had to be deleted before the hoisted 1.2.6 resolved.
**Suggested fix:** constrain `@scure/base` to `^1.2` through `overrides` in the root manifest, or raise it with `did-jwt`.
## Problem 2 — prepare runs before dependencies exist, and --ignore-scripts does not stop it
`packages/ats/contracts/package.json`:
```json
"scripts": { "prepare": "npx hardhat compile" }
```
npm runs `prepare` for a workspace during install, before that workspace's dependencies are linked. So the first thing a clean clone does is invoke `hardhat` with no `node_modules`.
`npm install --ignore-scripts` did not suppress it — same failure, same empty `node_modules`. The only thing that worked was editing the `prepare` script out, installing, then compiling explicitly.
**Suggested fix:** drop `prepare` and rely on `ats:build` / `ats:setup`, which already run `ats:contracts:build`. Compiling contracts is a build step rather than a package-preparation step, and placing it in `prepare` makes a clean clone depend on a tool it has not installed yet.
## A working sequence, for anyone hitting this meanwhile
```bash
# 1. remove the prepare hook from packages/ats/contracts/package.json
# 2. add to the root package.json:
# "overrides": { "@scure/base": "1.2.6" }
npm install
rm -rf node_modules/did-jwt/node_modules/@scure/base # force the hoisted copy
npm run ats:contracts:build
npm run ats:sdk:build
npm run ats:web:dev
```
After that the web app starts and works correctly — we issued an ERC-1400 equity through it on Hedera testnet with no further trouble. This is purely a first-install problem.
Contributor guide
Research direction
Reproduce the clean-clone failure with npm install, then inspect package.json at the repository root and packages/ats/contracts/package.json, especially the overrides and prepare script. Verify the change with a fresh install and the existing ats:contracts:build, ats:sdk:build, and ats:web:dev commands; done means installation succeeds without manual edits and the listed builds run.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100