Thanks for wanting to help out. ODE is a young project and the community keeps it moving, so whether you're here to write code, fix docs, test the platform, or just share how you use it, you're welcome.
This guide covers the practical stuff: how to report problems, how to set up a local environment, and what we expect from pull requests. If you haven't already, read the README for an overview of the project and what the ensemble (formulus, formplayer, synkronus, and friends) actually is.
There is more than one way to contribute:
- Code - fix bugs, build features, or start with the issue tracker and look for
good first issueorhelp wantedlabels. - Documentation - the docs always need polish, both here and on opendataensemble.org. If a section is confusing or outdated, improve it.
- Testing and feedback - run the apps, sync data, and report what breaks or what feels rough.
- Community - help other users on the forum, answer questions, and share how ODE works in your own way.
- Questions go to the forum, not issues. If you're trying to understand how something works or how to set it up, ask on the community forum. Issues are for bugs and concrete change requests.
- Talk first for anything significant. If you want to build a new feature, do a big refactor, or change behavior, open an issue first and describe your idea before writing code. A short conversation up front saves you from building the wrong thing.
- Be patient with people. ODE welcomes contributors of all skill levels. Be kind, explain things, and assume good intent.
This is a monorepo, so the setup depends on the project you're touching. The full instructions live in each project's README and AGENTS.md; here's the short version.
- git
- Node.js with Corepack enabled (we use
pnpm) - Go for the Synkronus backend and CLI
- Rust if you're working on ODE Desktop
-
Clone your fork and add the upstream remote:
git clone https://github.com/<your-username>/ode.git cd ode git remote add upstream https://github.com/OpenDataEnsemble/ode.git
-
Create a branch for your work, based on the latest
dev(the default branch):git fetch upstream git switch -c my-change upstream/dev
-
When ready, push the changes to your for and create a PR from GitHub
git push -u origin my-change
Tip: in a fresh clone, install the design tokens first, then formplayer and the shared components because they depend on tokens being built.
- formulus - React Native mobile app. See
formulus/README.md(and theformulus/AGENTS.mdpre-flight checklist). Lint/format:cd formulus && pnpm run lint,pnpm run format:check. - formulus-formplayer - form UI in a WebView (React). See
formulus-formplayer/README.md. Run it withcd formulus-formplayer && pnpm start. - synkronus - Go backend. See
synkronus/README.md(Development Setup) andsynkronus/DOCKER.md. - synkronus-cli - Go command-line client. See
synkronus-cli/README.md; pre-flight iscd synkronus-cli && go build ./cmd/synkronus. - synkronus-portal - web admin UI (React). See
synkronus-portal/README.mdfor both Docker and Dockerless setups. - desktop - Tauri app. See
desktop/README.md(Quick start). - docs - public Docusaurus site under
docs/. It is an independent npm project (cd docs && npm install && npm start); do not use pnpm there. Seedocs/README.md. - packages/tokens and packages/components - see
packages/tokens/CONTRIBUTING.mdandpackages/components/CONTRIBUTING.md.
The quickest cheat sheet for any package is its AGENTS.md file - it lists the day-to-day commands and exactly what to run before a pull request.
- Keep a pull request focused. One logical change per PR. If you notice something unrelated, open a separate issue instead of folding it in.
- Follow the conventions of the project you're in. Match the style of the surrounding code, use the existing helpers and libraries, and reach for shared tokens and components where they already exist.
- Run the checks before you push. Every package has lint, format, and test commands — run them locally so CI isn't the first to catch problems. Each package's
README.md/AGENTS.mdlists the exact commands. - Add or update tests for new behavior, and update the docs if your change alters how something works.
We use Conventional Commits. Keep messages short and specific:
feat(formulus): add draft delete confirmation
fix(synkronus): handle missing user on refresh
docs(portal): clarify env var setup
The scope is usually the package or area you touched (formulus, formplayer, synkronus, portal, tokens, docs, and so on), and the message should say what changed and why.
- Run the pre-flight checks for every package you changed. The per-package
AGENTS.mdfiles document these (typically lint, format, format:check, and tests - sometimes typecheck or build too). - Use the pull request template. The PR title must be a valid Conventional Commit, and the description should explain how the change works and why it's needed.
- Link the issue you're working on with
Closes #123so it closes automatically when the PR is merged. - Open a draft PR if the work is still in progress, then mark it ready for review when it's complete.
- Watch the CI status. Check that the workflows for your change pass; a failing check is usually quick to fix.
After you open the PR, a maintainer will review it. Expect feedback and a round or two of changes - that's a normal part of the process, not a rejection. Stick around to answer questions and push updates to the same branch.
Search the issue tracker for existing reports first, then use the issue templates — they describe exactly what to include. For a bug report that means what you did, what you expected, and what happened instead, plus which component and version.
Do not report security issues through public issues. Follow SECURITY.md and email security@opendataensemble.org instead. Reporting privately means the problem isn't exposed publicly before a fix exists, and we respond quickly.
The repository is MIT licensed, with one exception: synkronus-cli is currently GPL-2.0-or-later while it depends on a GPL-classified QR library - see THIRD_PARTY_NOTICES.md for details. Contributions land under the license of the project they're in.
- Community forum — questions, ideas, and general discussion.
- opendataensemble.org — project site and documentation.
- Repository on GitHub — issues, discussions, and releases.
Every contribution, big or small, is what keeps ODE moving. Thanks for joining the ensemble.