The full-fledged Enketo web application for the ODK ecosystem
Pull request Compare This branch is even with kobotoolbox:master.
Type Name Latest commit message Commit time
Failed to load latest commit information.
app changed: [MAJOR] modernized client-side JS, closes #66 Nov 5, 2018
config bodyParser limit is overridden from config value at app start-up Dec 4, 2018
doc Fix typo on #12 Nov 25, 2018
locales changed: updated Spanish translation Dec 7, 2018
logs changed: added logs folder to repo, log formatting Dec 1, 2015
public changed: [MAJOR] modernized client-side JS, closes #66 Nov 5, 2018
setup changed: simplified installation and re-organized setup files Jul 27, 2018
test changed: [MAJOR] modernized client-side JS, closes #66 Nov 5, 2018
tools changed: converted all server-side JS to ES6, closes kobotoolbox#389 Mar 9, 2018
.dockerignore changed: docker setup overhaul Dec 20, 2016
.eslintrc.json fixed: regression in es6 conversion with error handlers Mar 19, 2018
.gitignore changed: JS built files are now cleaned up and better separated from … Sep 11, 2018
.jsbeautifyrc changed: jshint to eslint to prepare for ES6 conversion Feb 27, 2018
.travis.yml changed: simplified installation and re-organized setup files Jul 27, 2018 changed: updated Spanish translation Dec 7, 2018
Dockerfile fixed: Docker installations fail because the `Dockerfile` specifies N… Jul 31, 2018
Gruntfile.js changed: [MAJOR] modernized client-side JS, closes #66 Nov 5, 2018
LICENSE initial setup: app structure, dependencies, readme, testing tools, bu… May 8, 2014 changed: updated Spanish translation Dec 7, 2018
Vagrantfile changed: simplified installation and re-organized setup files Jul 27, 2018
app.js changed: converted all server-side JS to ES6, closes kobotoolbox#389 Mar 9, 2018
babel.config.js changed: [MAJOR] modernized client-side JS, closes #66 Nov 5, 2018
buildFiles.js fixed: build system aliases (to configure widgets) Nov 13, 2018
package-lock.json fixed: build system aliases (to configure widgets) Nov 13, 2018
package.json fixed: build system aliases (to configure widgets) Nov 13, 2018
rollup.config.js fixed: build system aliases (to configure widgets) Nov 13, 2018

Enketo Express Build Status Dependency Status Codacy Badge

The modern Enketo Smart Paper web application.

How to install a test/development server


  1. Install JS prerequisites: Node.js (8.x LTS), Grunt Client.
  2. Install Redis
  3. Install build-essential, curl and git with (sudo) apt-get install build-essential git curl
  4. Clone this repository
  5. Install dependencies with npm install from the project root
  6. Create config/config.json to override values in the default config. Start with cp config/default-config.json config/config.json
  7. Build with grunt from the project root

Using vagrant:

This takes several shortcuts. Do not use for production!

  1. Install Vagrant and VirtualBox
  2. Run vagrant up from project folder and wait until it completes *
  3. Log in to the VM with vagrant ssh and run cd /vagrant && npm start

The app should now be running on localhost:8006. You can test the API in a different console window with: curl --user enketorules: -d "server_url=" http://localhost:8006/api/v2/survey.

* sometimes vagrant up fails for reasons beyond our control - e.g. if external resources are temporarily unavailable. Try running vagrant reload --provision to resolve this.

Using Docker:

  1. Install Docker Compose.
  2. Create a config file at config/config.json specifying at minimum an API key.
  3. (Optional) For HTTPS, copy your SSL certificate and key files to setup/docker/secrets/ssl.crt and setup/docker/secrets/ssl.key respectively (take care not to commit these files back to any public git repository). Plain HTTP requests to Enketo Express will be automatically redirected to HTTPS.
  4. Execute docker-compose up -d from the setup/docker directory and wait to see e.g. Worker 1 ready for duty....
  5. To stop, execute docker-compose stop from the setup/docker directory. Database dumps from the main Redis instance will be mapped into the directory setup/docker/redis_main_data/.

The app should now be running on localhost.

How to install a production server

See this tutorial for detailed instructions. Another option, for some people, is to deploy with Heroku.

How to configure

All configuration is normally done in config/config.json. This file only has to contain the default properties that you'd like to override. For some it may be preferrable to include all properties, to avoid surprises when the default configuration changes. Others may want to reduce hassle and keep the config.json as small as possible to automatically deploy configuration changes (e.g. new widgets). After editing the configuration, the app will need to be restarted.

As an alternative, there is an option to use environment variables instead of a config/config.json file. If the config/config.json file is missing Enketo will assume configuration is done with environment variables. A combination of both options is not supported. See config/sample.env for more information on equivalent environment variable names.

The default production configuration includes 2 redis instances. You can greatly simplify installation by using 1 redis instance instead (for non-production usage). To do this set the redis.cache.port to 6379 (same as redis.main.port). To set up 2 instances properly for production, you might find the vagrant setup steps in useful.

For detailed guidance on each configuration item, see this document.

To configure your own custom external authentication also see this section.


Always use the API to obtain webform URLs. Never try to craft or manipulate Enketo webform URLs yourself. This will make your Enketo integration future proof in case the URL structure changes. The API is stable, but webform URLs definitely are not.

The API is accessible on /api/v2 and /api/v1. See the documentation on how to use it.

How to run

Run with npm start from project root.

You can now check that the app is running by going to e.g. http://localhost:8005 (depending on your server and port set in config/config.json or the port forwarding set up in Vagrant (default is 8006))

For a production server, we recommend using pm2 or forever to manage the node app.

How to update

  • update git repository with git pull (Check out a specific release (git tag) for a production server)
  • update dependencies with npm install --production (This will run the CSS/JS builds automatically as well. If not, use grunt manually afterwards). You may have to remove package-lock.json.
  • restart app

Developer tools

  • Install nodemon to automatically restart the server when a file changes.
  • Install gulp to automatically update the translation keys.
  • Install mocha to run tests.

The easiest way to start the app in development and debugging mode with livereload is with grunt develop.

Browser support

See this faq.

Enketo endeavors to show a helpful (multi-lingual) error message on unsupported browsers when the form is loaded to avoid serious issues.


The default theme can be set in config/config.json. The default theme can be overridden in the form definition.

The recommended way to customize themes is to either:

  • Create an issue (and fund or send a pull request) for changes to the existing themes, or
  • Create your own theme in your own enketo-express port and add your custom theme in its own folder here. No other changes are required. A succesful rebuild with grunt, and your theme will become active when the app starts. The advantage of using this method instead of editing the existing themes, is that you will not have merge conflicts when you update your port! Add a print-specific version of your theme and use the same filenaming convention as the built-in themes.

See also this further guidance.


This app can manage OpenRosa form authentication for protected forms, i.e. it is possible to log in to forms with credentials set in your OpenRosa Server (e.g. Aggregate/KoBo), just like in ODK Collect.

Alternatively, you could make use various external authentication methods, i.e. using the authentication management of your form and data server.

For more information see this documentation page and the configuration documentation.


There are two major security considerations to be aware of. Both of these result in the need to run this application on https with a valid SSL certificate.

API security is mainly arranged by the secret API key set up in config/config.json. This API key is sent in cleartext to Enketo by the form/data server (such as ODK Aggregate) and can easily be intercepted and read if the transport is not secure. Somebody could start using your Enketo Express installation for their own form/data server, or obtain the URLs of your forms. Using secure (https) transport mitigates against this hazard. Security increases as well by populating the server url in config/config.json. Also, don't forget to change your API key when you start running Enketo Express in production.

Form authentication is only secure when Enketo is running on https. To avoid leaking form server credentials, authentication is automatically disabled when the app is accessed in a 'production' environment on 'http'. If you have to to run the app on http in a production environment, you can bypass this security by setting "allow insecure transport": true in config/config.json. The only use case this would be acceptable in is when running the app on a local protected network (e.g. in the KoBo VM).


The user interface was translated by: Darío Hereñú(Spanish), Viktor S. (Russian), Alexander Torrado Leon (Spanish), Peter Smith (Portugese, Spanish), Przemysław Gumułka (Polish), Niklas Ljungkvist, Sid Patel (Swedish), Katri Jalava (Finnish), Francesc Garre (Spanish), Sounay Phothisane (Lao), Linxin Guo (Chinese), Emmanuel Jean, Renaud Gaudin (French), Trần Quý Phi (Vietnamese), Reza Doosti, Hossein Azad, Davood Mottalee (Persian), Tomas Skripcak (Slovak, Czech, German), Daniela Baldova (Czech), Robert Michael Lundin (Norwegian), Margaret Ndisha, Charles Mutisya (Swahili), Panzero Mauro (Italian), Gabriel Kreindler (Romanian), Jason Reeder, Omar Nazar, Sara Sameer, David Gessel (Arabic), Tino Kreutzer (German), Wasilis Mandratzis-Walz (German, Greek), Luis Molina (Spanish), Martijn van de Rijdt (Dutch).

Send a message if you'd like to contribute! We use an easy web interface provided by Transifex.


The development of this application was funded by KoBo Toolbox (Harvard Humanitarian Initiative), iMMAP, OpenClinica, and Enketo LLC. The Enketo-core library (the form engine + themes) used in this application obtained significant funding from SEL (Columbia University), the Santa Fe Institute, Ona and the HRP project.


See the license document for this application's license.

Note that some of the libraries used in this app have a different license. In particular note this one.

Note the 'Powered by Enketo' footer requirement as explained in enketo-core. This requirement is applicable to all Enketo apps, including this one, unless an exemption was granted.

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.

Change log

See change log