Contribution guide
Issues
You can use GitHub issues to request features and file bug reports. An issue is also a good place to ask questions. We are happy to help out if you have reached a dead end, but please try to solve the problem yourself first.
When creating an issue there are couple of things you need to remember:
Update to the latest version of objection if possible and see if the problem remains. If updating is not an option you can still request critical bug fixes for older versions.
Describe your problem. Answer the following questions: Which objection version are you using? What are you doing? What code are you running? What is happening? What are you expecting to happen instead? If you provide code examples (please do!), use the actual code you are running. People often leave out details or use made up examples because they think they are only leaving out irrelevant stuff. If you do that, you have already made an assumption about what the problem is and it's usually something else. Also provide all possible stack traces and error messages.
If possible, provide an actual reproduction The fastest way to get your bug fixed or problem solved is to create a simple standalone app or a test case that demonstrates your problem. There's a file called reproduction-template.js you can use as a starting point for your reproduction.
Please bear in mind that objection has thousands of tests and if you run into a problem, say with insert method, it doesn't mean that insert is completely broken, but some small part of it you are using is. That's why enough context is necessary. It's not enough to say, "insert fails". You need to provide the code that fails and usually the models that are used too. And let's say this again: don't provide made up code examples! When you do, you only write the parts you think are relevant and usually leave out the useful information. Use the actual code that you have tested to fail.
Pull requests
If you have found a bug or want to add a feature, pull requests are always welcome! It's better to create an issue first to open a discussion if the feature is something that should be added to objection. In case of bugfixes it's also a good idea to open an issue indicating that you are working on a fix.
For a pull request to get merged it needs to have the following things:
A good description of what the PR fixes or adds. You can just add a link to the corresponding issue.
Tests that verify the fix/feature. It's possible to create a PR without tests and ask for someone else to write them but in that case it may take a long time or forever until someone finds time to do it. Untested code will never get merged!
For features you also need to write documentation. See the development setup section for instructions on how to write documentation.
Development setup
Fork objection in github
Clone objection
git clone git@github.com:<your-account>/objection.js.git objectionRun
npm installat the root of the repoRun
docker compose upat the root of the repo- If you have local databases running, shut them down or port binding will conflict.
Create test users and databases by running
node setup-test-dbat the root of the repoRun
npm testin objection's root to see if everything works. The source is TypeScript insrc/and is compiled intolib/bynpm run build(tsc -p tsconfig.build.json), whichnpm testruns first. The tests and the package uselib/. The package entrysrc/objection.jsstays a small JavaScript file on purpose, so thatrequire()returns exactly the same object as before, and the PEG.js parsers insrc/queryBuilder/parsers/are generated JavaScript.Run
npm run docs:devand go tohttp://localhost:5173/objection.js/to see the generated documentation site when you change the markdown files in thedocfolder.
You can run the tests on a subset of databases by setting the DATABASES env variable
# Only run tests on sqlite. No need for docker compose.
DATABASES=sqlite3 npm testThe code runs on Node.js 24 and newer, so it can use everything Node.js 24 supports.
Two rules keep the compiled code as fast as the JavaScript it replaced:
- Don't re-export an imported binding (
export { x } from './x', or importingxand listing it inexport { ... }). tsc compiles it to a getter onexports, which puts the whole exports object of the module in V8's slow dictionary mode, and every call through it gets several times slower. Export a local constant instead:const x = importedX; export { x };.tests/unit/moduleExports.jsfails if a compiled module exports a getter. - Import JavaScript modules by name (
import { parse } from './parser'), not withimport * as, which wraps them in an object of getters.
Biome lints and formats the code. npm run lint checks both, and npm run format fixes what can be fixed automatically. Run it before committing; CI runs biome ci.