This is the common top-level contribution guide for the UI5/typescript monorepo. A sub-package may have an additional CONTRIBUTING.md file if needed.
Thanks for your interest in contributing! All forms of contribution are welcome — bug reports, fixes, documentation, new features, and reviewing other contributors' PRs.
All contributors must sign the DCO
This is managed automatically via https://cla-assistant.io/ pull request voter.
As artificial intelligence evolves, AI-generated code is becoming valuable for many software projects, including open-source initiatives. While we recognize the potential benefits of incorporating AI-generated content into our open-source projects there are certain requirements that need to be reflected and adhered to when making contributions.
Please see our guideline for AI-generated code contributions to SAP Open Source Software Projects for these requirements.
Open a GitHub issue on the topic that fits your case best:
- For
@ui5/dts-generator— issues with the generation logic itself. Issues in the generated UI5 type definitions usually originate from JSDoc comments in OpenUI5 / SAPUI5 — please open the ticket there in that case. - For
@ui5/ts-interface-generator— anything related to control-interface generation for TypeScript controls.
A reproducible example (a minimal repo or a TypeScript Hello World fork) is the single biggest thing that helps get an issue triaged quickly.
- A current Long-Term Support version of Node.js (>= 22; CI tests on 22.x and 24.x).
- Yarn 1.x — this repo uses yarn classic with workspaces.
- (optional) commitizen for managing commit messages.
The initial setup is trivial:
- clone this repo
yarn
The repo's .yarnrc enforces --frozen-lockfile, exact-version saves (save-prefix ""), and a pinned registry — that's intentional supply-chain hardening, please don't loosen it without discussion.
packages/ # public, published to npm
dts-generator/ # @ui5/dts-generator
ts-interface-generator/ # @ui5/ts-interface-generator
test-packages/ # private, never published
openui5-snapshot-test/
typed-json-model/
demos/ # private, never published
Only the two packages/* are released to npm. Everything under test-packages/* and demos/* is "private": true and is automatically ignored by Changesets.
This project enforces the conventional-commits commit message formats. The possible commits types prefixes are limited to those defined by conventional-commit-types. This promotes a clean project history and enabled automatically generating a changelog.
The commit message format will be inspected both on a git pre-commit hook and during the central CI build and will fail the build if issues are found.
It is recommended to use git cz to construct valid conventional commit messages.
- requires commitizen to be installed.
Use the package directory name as the scope when the change is package-specific:
feat(dts-generator): support union types in api.json
fix(ts-interface-generator): handle aggregations with cardinality 0..1
chore: bump root devDependencies
The scope is also what yarn changeset:auto uses to figure out which packages to bump (see Releases below). Breaking changes are signalled with a ! after the type/scope or a BREAKING CHANGE: footer in the body — either flips the bump to major.
Prettier is used to ensure consistent code formatting in this repository. This is normally transparent as it automatically activated in a pre-commit hook using lint-staged. However, this does mean that dev flows that do not use a full dev env (e.g editing directly on github) may result in voter failures due to formatting errors.
To run it manually:
yarn format:fix # rewrite files
yarn format:validate # check, no rewrite (this is what CI runs)See the respective sub-packages for instructions (if needed at all).
To build both publishable packages from the root:
yarn buildPer-package work uses yarn's workspace shorthand:
yarn workspace @ui5/dts-generator build
yarn workspace @ui5/ts-interface-generator testMocha and Chai are used for unit-testing.
- To run the tests, execute
yarn testin a specific sub-package.- Note that not all sub-packages contain tests.
When adding a feature or fixing a bug, please add or extend a test. PRs without tests will get a friendly nudge.
To run the full Continuous Integration build run yarn ci in either the top-level package or a specific subpackage.
- Fork the repo (or branch from
mainif you have write access). - Create a topic branch with a descriptive name (
feat/union-types,fix/aggregation-cardinality). - Make your change, with tests, in commits that each follow the conventional-commits format.
- Add a changeset (see Release Process below) — required for any change that should produce a new release.
- Push and open a PR against
main. - The CI workflows (
Continuous Integration,Lint Commit Messages,CodeQL) must all pass.
Reviews aim for two pairs of eyes on substantive changes; small fixes and chore commits may be merged with a single approval.
This monorepo uses Changesets for versioning and publishing. Each public package under packages/* keeps its own version (independent versioning) and its own CHANGELOG.md. Private packages under test-packages/* and demos/* are never released.
The release flow is fully automated through GitHub Actions — there's no local lerna, and no contributor needs npm-publish or push-to-main rights.
When your PR changes one or more public packages, add a changeset alongside your code change. Pick whichever of the three commands fits best:
| Command | When to use |
|---|---|
yarn changeset:auto |
Recommended for most PRs. Walks the conventional-commit history on your branch and writes one .changeset/auto-<sha>.md per qualifying commit (packages from the commit scope, bump from the type, summary from the subject). Idempotent — safe to re-run. Already-covered commits are skipped, so any hand-written changeset always wins. |
yarn changeset |
Interactive — pick packages, bump type, and write a summary by hand. Use when the auto-derived bump or summary is wrong (e.g. a chore: commit that secretly contains a feat:). The next :auto run will then skip the commit because it's covered. |
yarn changeset:empty |
Docs- or tooling-only PRs that touch no public package. Writes an empty .changeset/*.md so the "no changeset detected" hint goes away without producing any CHANGELOG entry. |
Whichever you pick, commit the resulting .changeset/*.md file alongside your code change.
How yarn changeset:auto chooses the bump:
Conventional-commit type (or marker) |
Bump |
|---|---|
feat: |
minor |
fix:, perf:, refactor:, chore:, build:, style: |
patch |
docs(<scope>): (only when scoped to a package) |
patch |
<type>!: or a BREAKING CHANGE: footer |
major |
ci:, anything scoped release |
skipped |
Commits whose only file changes are under packages/<pkg>/test/ are also skipped — test-only changes don't ship in the published tarball.
If a change does not warrant a release at all (CI tweaks, internal tooling, etc.) run yarn changeset:empty and commit the generated file — it satisfies the required changeset check without producing any package release.
The release itself happens entirely on GitHub. You don't need npm credentials or a clean local checkout.
- When a PR with at least one changeset is merged into
main, theReleaseworkflow opens (or updates) a singleVersion PackagesPR. That PR aggregates every pending changeset, bumps the affectedpackage.jsonversions, regenerates each package'sCHANGELOG.md, and refreshesyarn.lock. - Review and merge that
Version PackagesPR when you're ready to cut a release. - Merging it triggers the same workflow again, this time on the
publishpath:changeset publishruns, the new versions go to npm (with npm provenance), and matching git tags are pushed. - Spot-check the newly published artifacts on npmjs.com.
You can also trigger the workflow manually via Actions → Release → Run workflow — useful if a previous run failed mid-publish. Re-running publishes whatever versions are currently on main that haven't been released yet (changeset publish is idempotent — it skips versions already on the registry).
The workflow prefers npm OIDC trusted publishing (no token required). If OIDC isn't configured for a package, it falls back to secrets.NPM_BOOTSTRAP_TOKEN. The "Detect token usage" step in the workflow prints which path is active.
Not currently configured. If we need them, changeset pre enter <tag> is the standard mechanism — open an issue first to discuss the tag scheme.
To upgrade the version of the dependencies, npm-check-updates is wired up at the root:
yarn ncu # list outdated packages across the workspace
yarn ncu-u # apply the bumps to every package.json
yarn install # refresh yarn.lock
yarn ci # sanity-check before opening the PR- For UI5 + TypeScript usage questions, the ui5.github.io/typescript docs are the best starting point.
- For sample applications, see the TypeScript Hello World app and the TypeScript branch of the UI5 CAP Event App.
- For tooling-specific bugs, please open an issue.