JHipster is a Yeoman-based code generator (TypeScript, ESM, Node — see engines in package.json for the required version) that scaffolds Spring Boot + Angular/React/Vue applications. See ARCHITECTURE.md, BLUEPRINTS.md, and DEVELOPMENT.md for background context.
Trust order when docs disagree: package.json scripts and the current source tree are the source of truth. Prose docs (including DEVELOPMENT.md) may be stale — verify commands against package.json before running them.
- Install:
npm ci(also compiles viaprepare→build). - Build:
npm run build(runsclean→tsc→ copy non-TS template files +.d.tstodist/, thenbin/fix-bin.cjs). Usenpm run compilealone for a faster TS-only recompile. - Type-check tests:
npm run check-types(tsc -p tsconfig.spec.json). - Lint:
npm run lint(eslint,--max-warnings 5). Auto-fix:npm run lint-fix(runs eslint--fixthenprettier --write). - Prettier check/format:
npm run prettier:check/npm run prettier:format. - Full test (lint + type-check + mocha):
npm test. Runs esmocha overtest generators cli .blueprint libwith--forbid-only. - Fast test (skip lint/type-check):
npx esmocha. - Single test file / directory:
npx esmocha <path>(add--no-parallelfor clearer stack traces). - Update snapshots:
npm run update-snapshot -- <path>(single) ornpm run update-snapshots(all). Equivalent:npx esmocha <path> --no-parallel --update-snapshot. - JDL-only tests:
npm run jdl:test(watch:npm run jdl:test-watch).
Snapshots live next to specs as *.snap and are committed. Never hand-edit them — regenerate.
Always run npm run prettier:format (or npm run lint-fix) before committing so changes match the project's Prettier configuration. CI will fail otherwise.
Two options (see DEVELOPMENT.md):
- JIT:
alias jhipster="$PWD/bin/jhipster.cjs"— no build step needed. - Linked build:
npm run build && npm link; rebuild after changes. On generated apps usejhipster --skip-jhipster-dependenciesplusnpm link generator-jhipsterso the dev version is picked up.jhipster --install-pathshows which copy is active.
- CLI entry:
cli/jhipster.cjs→cli/cli.ts(env checks) →cli/program.ts(commander parsing, generator/blueprint lookup) → spawns a Yeoman Environment which runs the selected generator. - Generator hierarchy (extend the lowest level that has what you need):
GeneratorBaseCore→GeneratorBase(blueprint composition) →GeneratorApplication(entity APIs). - Each generator lives in
generators/<name>/with a fixed layout:index.ts— re-exports the generator as default plus thecommand. Required for the exports map inpackage.json.generator.ts— priority task groups (see below).command.ts— CLI args/options/configs (consumed byparseJHipsterArguments/parseJHipsterConfigsand byprogram.tsto build the CLI).templates/— EJS templates rendered duringwriting/writingEntities.support/— exported helpers (part of the public API via./generators/*/support).internal/— non-exported helpers.resources/,jdl/— supporting data / JDL specs. Sub-generators nest undergenerators/<parent>/generators/<child>/and are exported via the same pattern.
- Priority lifecycle (order matters, see
ARCHITECTURE.mdfor full list):initializing→prompting→configuring→composing→loading→preparing→configuringEachEntity→loadingEntities→preparingEachEntity→preparingEachEntityField→preparingEachEntityRelationship→default→writing→writingEntities→postWriting→install→end. Use the matchingas<Priority>TaskGroup()helper on the generator to get typed task signatures. - Blueprints (
BLUEPRINTS.md): three flavors — replacement, side-by-side, standalone.GeneratorBasehandles composition; blueprinted sub-generators are discovered and composed inbeforeQueue. lib/holds shared, exported code:lib/jdl(Chevrotain-based JDL parser),lib/testing(test harness, also importable as#testing),lib/utils,lib/eslint,lib/ci. Keep cross-generator logic here, not inside an individual generator..blueprint/is the in-repo "dev blueprint" enabled when running via JIT. It provides sub-generators likegenerate-sample,generate-generator,from-issue,update-spring-boot, etc. — use these instead of ad-hoc scripts when generating samples for manual testing.- Build output in
dist/is what gets published. Theexportsmap inpackage.jsondefines the public API surface — don't import across generatorinternal/boundaries. - Never edit
dist/directly. Modify source incli/,generators/,lib/, etc., then rebuild withnpm run build(ornpm run compilefor TS-only).
- ESM + TypeScript everywhere;
"type": "module"inpackage.json. Use.ts/.mts. Tests are*.spec.tsrun byesmocha. - Task groups: define priorities as getters returning the result of
this.as<Priority>TaskGroup({...}). Never call tasks directly — the Yeoman environment orchestrates them. - Config access: prefer
this.jhipsterConfig(persists to.yo-rc.json),this.jhipsterConfigWithDefaults(read-only with defaults applied), and theapplication/entity/field/relationshipcontext objects injected into tasks. Derived booleans (e.g.entity.dtoMapstruct,field.fieldTypeInteger) belong inpreparing*priorities, not in templates. - Writing files: use
this.writeFiles({ blocks, context })withconditionfunctions on blocks rather than branching inside templates. UseeditFile(path, transform)or the needle APIs onsourceinpostWritingto inject into already-written files. - Templates: EJS (
.ejs). Two-space indent for template logic; generated file's own rules apply to content. Factor shared fragments into.ejssub-templates included via<%- include('../path', { ... }) -%>. - Commit messages (enforced at review): imperative present tense, lowercase first letter, no trailing dot, header ≤100 chars. Reference issues in footer (
Fix #1234). Use[ci skip]for docs-only commits. - Tests required for every feature or bug fix. When behavior touches generated output, update/extend snapshots rather than asserting strings by hand.
- Path aliases for tests:
#testing→lib/testing/index.ts,#test-support→test/support/index.ts. - Node version: CI and local must match
enginesinpackage.json; avoid APIs only in newer releases.