Contributing to opening_hours
September 2, 2026 · View on GitHub
We're excited you're interested in contributing! This document outlines our contribution guidelines and processes.
Branching Model
We use a branching model inspired by Gitflow:
main: This is the primary development branch and default git branch. All new feature development and bug fixes should be based on this branch. Pull requests for new features or fixes should target themainbranch.
Getting Started
- Fork the repository.
- Clone your fork locally:
git clone https://github.com/opening-hours/opening_hours.js - Create a new branch from
mainfor your work:git switch -c feature/your-feature-name mainorgit switch -c bugfix/issue-description main. - Make your changes and commit them with clear, descriptive messages.
- Push your branch to your fork:
git push origin feature/your-feature-name. - Open a Pull Request (PR) against the
mainbranch of the upstream repository.
Pull Request Process
- Ensure your PR includes a clear description of the changes and why they are being made. Reference any relevant issues.
- Your PR will be reviewed by a maintainer.
- Once approved and CI checks pass, your PR will be merged into the
mainbranch.
Releasing
When the main branch is deemed ready for a new release:
- A maintainer prepares the release in a
release/branch based onmain. - The maintainer updates school holiday data:
node scripts/fetch-school-holidays.mjsand commits any changes. - The maintainer runs
make release-preparelocally. - The maintainer decides if a release candidate should be released, if rc
npx commit-and-tag-version --prerelease=rcshould be run locally, if notmake release-localshould be run. In case a maintainer does not have a separate OpenSSH/OpenPGP key for releases, they can use their regular signing key. The maintainer pushes the signed git tag to their repo fork. - This pull request will be reviewed and then merged into
main - ypid who is currently the only one who can release to npmjs.com gets assigned the pull requests, pulls the signed git tag and runs
make release-publishon their machine and finally merges the pull request. - ypid creates a release on GitHub and marks it as latest.
Translation Contributions
Translating the evaluation tool and the map
The web-based evaluation tool and map use i18next for translation. Translations can be made in the file js/i18n-resources.js. Just copy the whole English block, change the language code to the one you are adding and make your translation. You can open the index.html to see the result of your work. Week and month names are translated by the browser using the Date.toLocaleString function.
Note that this resource file does also provide the localization for the opening_hours_map. This can also be tested by cloning the project and linking your modified opening_hours.js working copy to the opening_hours.js directory (after renaming it) inside the opening_hours_map project. Or just follow the installation instructions from the opening_hours_map.
Translating Error Messages and Warnings
The core library uses a custom lightweight i18n implementation. Translations for error messages and warnings can be made in the file locales/translations.yaml. You are encouraged to test your translations. Checkout the Makefile and the test framework for how this can be done.
Word Error Correction System
The word error correction system is automatically generated using the scripts/gen_word_error_correction.mjs script, which creates corrections for date/time-related terms across 141+ languages using native internationalization API Intl. The system generates over 2,000 automatic corrections for common misspellings and variations of month names, weekday names, and other temporal terms.
Manual corrections can be added to src/locales/word_error_correction_manual.yaml for cases that require human curation or language-specific corrections that cannot be automatically generated. The build system automatically combines both automatic and manual corrections into the final word_error_correction.yaml file used by the library.
To regenerate the word error corrections:
make src/locales/word_error_correction.yaml
Holiday Data Contributions
Please do not open issues for missing holidays. It is obvious that there are more missing holidays then holidays which are defined in this library. Instead consider if you can add your missing holidays and send me a pull request or patch. If you are hitting a problem because some holidays depend on variable days or something like this, consider opening a unfinished PR so that the more complicated things can be discussed there.
Holidays can be added to the file index.js. Have a look at the current definitions for other holidays.
Please refer to the holiday documentation for more details about the data format.
Please consider adding a test (with a time range of one year for example) to see if everything works as expected and to ensure that it will stay that way. See under testing.
In case your holiday definition does only change the holiday_definitions variable (and not core code) it is also ok to test the definition using the scripts/PH_SH_exporter.js script. In that case writing a test is not required but still appreciated. Example: ./scripts/PH_SH_exporter.js --verbose --from=2016 --to=2016 --public-holidays --country dk --state dk /tmp/dk_holidays.txt
Core Code Contributions
Testing
Be sure to add one or more tests if you add new features or enhance error tolerance or the like. See under testing.
Commit Message Convention
We follow the Conventional Commits specification. The minimum required format is:
<type>[(optional scope)]: <subject>
Optionally with body and footer:
<type>(<scope>): <subject>
[optional body]
[optional footer]
Commit Types:
feat: A new featurefix: A bug fixdata: Updates to holiday/locale data filesdocs: Documentation only changesstyle: Code style changes (formatting, missing semicolons, etc.)refactor: Code changes that neither fix bugs nor add featuresperf: Performance improvementstest: Adding or updating testsbuild: Changes to build system or dependenciesci: Changes to CI configurationchore: Other changes that don't modify src or test files
Scope (optional):
The scope indicates the part of the codebase being changed. Common scopes include:
parser: Parser/tokenizer changesholidays: Holiday definition logic (not data updates)locales: Translation/i18n changesrollup: rollup changesnpm: npm changestest: Test infrastructuredeps: Dependency updatesevaluation-tool: Evaluation tool written in HTML, CSS, JS- Country codes (
de,fr,us, etc.): Country-specific changes
Examples:
feat(parser): add support for week ranges with step
fix: resume periodic week schedules mid-range
data(holidays): update Argentina 2026 public holidays
data(de): update school holidays for Bavaria 2026
docs(readme): add installation instructions for Deno
build(rollup): migrate to ESM output format
test: add coverage for periodic week schedules
Note: The scope is optional. When in doubt, omit it rather than guessing.
The changelog is automatically generated from these commit messages. Only feat, fix, data, docs, and refactor commits appear in the changelog.
Commit Hooks
Note that there is a git pre-commit hook used to run and compare the test framework before each commit. Hooks are written as shell scripts using husky and should be installed to git automatically when running npm install. If this does not happen, you can manually run node --run postinstall.
Reporting Issues
- Bugs: Open an issue with detailed reproduction steps
- Enhancements: Open an issue to discuss before starting implementation
Documentation
All functions are documented, which should help contributors to get started.
The documentation looks like this:
/** List parser for constrained weekdays in month range {{{
* e.g. Su[-1] which selects the last Sunday of the month.
*
* @param {Array<ParserToken>} tokens List of token objects.
* @param {number} at Position where to start.
* @returns {Array<number>} 0. Constrained weekday number.
* 1. Position at which the token does not belong to the list any more (after ']' token).
*/
function getConstrainedWeekday(tokens, at) {}
The opening brackets {{{ (and the corresponding closing onces) are used to fold the source code. See Vim folds.
Thank you for contributing!