Guide for contributors

This project follows a standard fork and pull model for accepting contributions via GitHub pull requests:

  1. Pick or report an issue
  2. Write code
  3. Write tests
  4. Update the documentation
  5. Submit a pull request

Pick or report an issue

The beginner-friendly label flags open issues where there is general agreement about the best way forward, and where the fix is likely to be relatively straightforward for someone with Scala experience. The help wanted label is a little more general, and indicates issues that may be much more challenging or have unresolved questions that need additional discussion.

When you begin working on an issue, please leave a comment to notify others that the issue is taken, and join us in the Gitter channel if you have any questions along the way.

We always welcome bug reports and feature requests—please don’t feel like you need to have time to contribute a fix or implementation for your issue to be appreciated.

Write code

The design principles document outlines some of the practices followed in the circe codebase. In general the public API should be purely functional, but the implementation is free to use non-functional constructions for the sake of performance—we want correctness, of course, but internally we’re willing to have this correctness verified by tests rather than the compiler when necessary. That said, performance-motivated optimizations should be based on evidence, not speculation, and a functional style should be preferred whenever possible. When in doubt, get in touch on Gitter or look around the codebase to see how things are done.

circe uses a fairly standard Scalastyle configuration to check formatting, and it may be useful to make your IDE aware of the following rules:

  • Code and comments should be formatted to a width no greater than 100 columns.
  • Files should not contain trailing spaces.
  • Imports should be sorted alphabetically.

When in doubt, please run sbt scalastyle and let us know if you have any questions.

Write tests

circe uses three testing libraries: Discipline, ScalaCheck, and ScalaTest, and organizes tests according to the following guidelines:

  • In general tests live in the tests sub-project. This allows e.g. tests for codecs in the core module to be able to use the Jawn parser without circular dependencies between sub-projects.
  • For experimental or stand-alone modules, it may be appropriate for tests to live in the project.
  • Most test suites should extend io.circe.tests.CirceSuite, which provides many useful type class instances and other tools.
  • Write tests that verify laws using Discipline whenever you can, then property-based tests using ScalaCheck, then behavior-driven tests.
  • An assertion in regular tests should be written with assert and === (which in the context of CirceSuite is Cats’s type-safe equality operator, not the operator provided by ScalaTest).
  • An assertion in properties (inside check) should be written with ===.

You can run sbt +validateJVM to run Scalastyle checking and the JVM tests. sbt +test will run all tests, but requires a lot of time and memory. Unless your contribution directly touches Scala.js-related code, it’s generally not necessary to run the Scala.js tests—we’ll verify compatibility before the next release.

Update the documentation

Consider whether circe users would benefit from documentation about a feature you’ve added or a change you’ve made. Currently, the documentation is composed of two parts:

  • The API documentation
    • Generated from Scaladoc comments
    • Generated by running sbt docs/unidoc
    • Written to e.g. docs/target/scala-2.12/unidoc (depending on Scala version)
  • The microsite
    • A compilation of examples on how to use Circe and also explains some of the design decision
    • Generated from the markdown files in docs/src/main/tut
    • Generated by running sbt docs/makeMicrosite (needs the Jekyll 4.0.0+ static site generator installed)
    • After generating, if you want to serve the site locally, you can run e.g. (cd docs/target/scala-2.12/resource_managed/main/jekyll && jekyll serve -b /circe) (depending on Scala version)

Submit a pull request

  • Pull requests should be submitted from a separate branch (e.g. using git checkout -b "username/fix-123").
  • In general we discourage force pushing to an active pull-request branch that other people are commenting on or contributing to, and suggest using git merge master during development. Once development is complete, use git rebase master and force push to clean up the history.
  • The first line of a commit message should be no more than 72 characters long (to accommodate formatting in various environments).
  • Commit messages should general use the present tense, normal sentence capitalization, and no final punctuation.
  • If a pull request decreases code coverage more than by 2%, please file an issue to make sure that tests get added.