This is the Enketo web forms monorepo. Enketo is an open source project that produces web form software for the ODK ecosystem.
- Enketo Core: Enketo's web form engine, intended for embedding in a web application
- Enketo Express: Enketo's integrated web application, embedding Enketo Core and providing integration with OpenRosa form servers
- Enketo Transformer: used by Enketo to transform XForms into the format consumed by Enketo Core
- OpenRosa XPath Evaluator: Enketo's implementation of the OpenRosa XPath extensions, used in Enketo Core
- Enketo Transformer Web (example): example app demonstrating client-side usage of Enketo Transformer
Enketo was initiated in 2009 by Martijn van de Rijdt as a web-based alternative or complement to ODK Collect. It has become a core component of the ODK ecosystem and been adopted by several organizations beyond that ecosystem.
Since 2021, Enketo has been maintained by the ODK team. The ODK team's goals have been to increase alignment with ODK Collect, improve error messages to help users get out of bad states and improve long-term maintainability by modernizing the code base, removing code duplication, and simplifying state mutation.
Important
The ODK team will transition out of being primary maintainers of Enketo by the end of 2024. We are currently seeking new maintainers.
Please use the issues for discussion (but we will also continue to respond on the ODK forum).
There are two major ways to use Enketo: embedding the client-side Enketo Core library in a broader frontend or using the Enketo Express service through its APIs. Which you choose depends on the functionality you what to implement in your host app (for example, Enketo Core doesn't provide offline caching of in-progress submissions, form transformation, or form URL management) and whether or not you already implement the OpenRosa APIs.
To use Enketo Core, see its README.
The recommended way to run Enketo Express is using Docker. We publish a minimal image which builds Enketo Express using the default configuration and then launches it. You will need to supply a configuration appropriate for your environment which must set at least the "linked form and data server", "api key", and secrets. You will also need to run redis
and make sure that Enketo Express can talk to both the redis
database(s) and a form server. See a simple example docker-compose
file for running a full platform on a single host with ODK Central. Another common configuration is to run Enketo Express on a separate host. Learn more about configuring Enketo Express in its README.
Important
If you used the Enketo Express Docker image from before the monorepo migration, you will need to make adjustments:
- Paths have changed. The working directory was previously the Enketo Express root so you would put your config at
config/config.json
. Now it is the Enketo monorepo root so your config must go topackages/enketo-express/config/config.json
. - Previous versions generated and templated in secrets using a Python script. If you need a templated configuration, you need to manage that yourself in your deployment infrastructure.
- Previous versions installed
pm2
and started Enketo Express with it.
- Node: Enketo supports the current Node LTS environments (presently versions 18 and 20). Local development targets the latest LTS release (20).
- Yarn: Package management and monorepo tasks use Yarn 1 ("classic").
- Volta: It is highly recommended to use Volta to manage Node and Yarn versions automatically while working in Enketo.
For running Enketo Express:
- redis
- An OpenRosa form server (ODK Central, Ona, Kobo, etc)
yarn install
Important: While many tasks you'll use during development are still package-specific, all tasks should be run from the project root (not within individual packages).
Current project-wide tasks:
-
Build all packages
yarn build
-
Lint is performed project-wide, checking code quality of all top level and package files.
yarn lint
Package-specific tasks are run with yarn workspace [package-name] ...
, e.g.
yarn workspace enketo-core test
yarn workspace enketo-express start
You can see additional tasks in each respective package's README and/or package.json
.
If you're coming form one of Enketo's pre-monorepo packages, you can generally continue to use the same tasks you used previously, with the aforementioned yarn worskpace [package-name]
prefix.
If you've previously used grunt
commands, you can now use yarn workspace [package-name] grunt ...
. This will use the local grunt
dependency, rather than whatever version you may have installed globally.
Some release preparation steps should be performed "bottom up", i.e. up the package dependency chain. This order is currently:
packages/openrosa-xpath-evaluator
packages/enketo-transformer
examples/enketo-transformer-web
:- Update the
enketo-transformer
dependency version if it will be released. - This is an internal package, and will not be "released", so its version should not be updated.
- Update the
packages/enketo-core
:- Update the respective
openrosa-xpath-evaluator
andenketo-transformer
dependency versions if either will be released. - Update
Form.requiredTransformerVersion
inpackages/enketo-core/src/form.js
, if Enketo Transformer will be released.
- Update the respective
packages/enketo-express
- Update the respective
enketo-transformer
andenketo-core
dependency versions if either will be released. - This package is not published to the NPM registry, but a Docker image is published with its version, so that should be updated as well.
- Update the respective
In each dependent package, if its dependencies are updated it should also be prepared for release (even if it has no other changes).
- Update all dependencies:
yarn upgrade
(this will honor semver version ranges in each respectivepackage.json
). Pay special attention to updates to these dependencies:node-libxslt
,node1-libxmljsmt-myh
,nan
: updating these may cause issues with particular versions of Node.node-forge
: if updated, you should also manually verify encrypted submissions end-to-end.
- Resolve any remaining dependency vulnerabilities:
yarn audit
, and update affected dependencies. Pay particularly close attention to non-dev dependencies.- Check Dependabot for any vulnerabilities which may have been missed by Yarn (like
npm audit
, these sometimes differ). You may have to checkyarn.lock
for subdependencies.
- Update the
CHANGELOG.md
for each package which will be released, with its new version/date and any released changes. Breaking changes should be noted explicitly. - Update package versions, "bottom up" (see above):
- For each package which has updates pending release, update its version in
packages/$PACKAGE_NAME/package.json
. We follow semantic versioning. - For each package which depends on that package, update its
package.json
to reference the new version. - If
enketo-transformer
has been updated, also updateForm.requiredTransformerVersion
inpackages/enketo-core/src/js/form.js
.
- For each package which has updates pending release, update its version in
- Ensure all updates are installed and applied in
yarn.lock
:yarn install
. This will also verify that each package's main build process succeeds. - Test all packages with updates applied:
yarn test
. - Create a release PR with all of these changes.
- Once merged, create GitHub releases for each package with a pending release.
- Tag and publish each release, "bottom up". GitHub Actions will publish each to the appropriate registry (e.g. NPM, GHRC, Docker Hub).
See each package for its licence.
Additionally, any product that uses enketo-core is required to have a "Powered by Enketo" footer, according to the specifications below, on all screens in which enketo-core or parts thereof, are used, unless explicity exempted from this requirement by Enketo LLC in writing. Partners and sponsors of the Enketo Project, listed on https://enketo.org/about/sponsors/ are exempted from this requirements and so are contributors listed in package.json.
The aim of this requirement is to force adopters to give something back to the Enketo project, by at least spreading the word and thereby encouraging further adoption.
Specifications:
- The word "Enketo" is displayed using Enketo's logo.
- The minimum font-size of "Powered by" is 12 points.
- The minimum height of the Enketo logo matches the font-size used.
- The Enketo logo is hyperlinked to https://enketo.org
Example:
The Enketo logo and Icons are trademarked by Enketo LLC and should only be used for the 'Powered by Enketo' requirement mentioned above (if applicable). To prevent infringement simply replace the logo images in /public/images with your own or contact Enketo LLC to discuss the use inside your app.