Skip to content

enketo/enketo

Repository files navigation

Enketo

This is the Enketo web forms monorepo. Enketo is an open source project that produces web form software for the ODK ecosystem.

Packages

Project status

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 (primarily Trevor Schmidt). Martijn continues to provide advice and continuity. The ODK project sets priorities in collaboration with its Technical Advisory Board.

Our current primary goals are:

  • Increasing alignment with ODK Collect, particularly in service of submission edits.
  • Improving error messages so that users can get out of bad states.
  • Improving long-term maintainability by modernizing code bases, removing code duplication, and simplifying state mutation.

Feature requests and project discussion are welcome on the ODK forum.

Using Enketo in your system

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.

Using Enketo Core

To use Enketo Core, see its README.

Using Enketo Express

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 to packages/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.

Development setup and local usage

Prerequisites

  • 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)

Install

yarn install

Running development tasks

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.

Releases

Some release preparation steps should be performed "bottom up", i.e. up the package dependency chain. This order is currently:

  1. packages/openrosa-xpath-evaluator
  2. packages/enketo-transformer
  3. 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.
  4. packages/enketo-core:
    • Update the respective openrosa-xpath-evaluator and enketo-transformer dependency versions if either will be released.
    • Update Form.requiredTransformerVersion in packages/enketo-core/src/form.js, if Enketo Transformer will be released.
  5. packages/enketo-express
    • Update the respective enketo-transformer and enketo-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.

In each dependent package, if its dependencies are updated it should also be prepared for release (even if it has no other changes).

Prepare to release

  1. Update all dependencies: yarn upgrade (this will honor semver version ranges in each respective package.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.
  2. 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 check yarn.lock for subdependencies.
  3. 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.
  4. 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 update Form.requiredTransformerVersion in packages/enketo-core/src/js/form.js.
  5. Ensure all updates are installed and applied in yarn.lock: yarn install. This will also verify that each package's main build process succeeds.
  6. Test all packages with updates applied: yarn test.
  7. Create a release PR with all of these changes.
  8. Once merged, create GitHub releases for each package with a pending release.
  9. Tag and publish each release, "bottom up". GitHub Actions will publish each to the appropriate registry (e.g. NPM, GHRC, Docker Hub).

License

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:

  1. The word "Enketo" is displayed using Enketo's logo.
  2. The minimum font-size of "Powered by" is 12 points.
  3. The minimum height of the Enketo logo matches the font-size used.
  4. The Enketo logo is hyperlinked to https://enketo.org

Example:

Powered by

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.