This page is our at-a-glance master list of all of our coding standards.
This is guided by the idea that good conversations are impossible if it isn't clear which standard(s) are being discussed.
- Every coding standard as a unique ID.
- Once assigned, this ID will not change.
- If the meaning of the coding standard changes over time, it will be given a new ID.
- Our IDs numeric, and use the
x.y.z
structure:x
is the impact level1.
for key2.
for major3.
for minor
y
is the category- numbers are assigned in the order that we invent the categories
z
is the next available number in that category
This is guided by the idea that, "if everything is top priority, then nothing is top priority."
We've split the coding standards up into three different levels of importance.
Level | Description |
---|---|
Key | These are the items that define our purpose. |
Major | Getting these right first time avoids significant bugs, expensive rework, and backwards-compatibility breaks. |
Minor | These are consistency / stylistic / philosophical points. |
To make it easier to find things, we've broken up the coding standards into these groups:
Category | ID | Description |
---|---|---|
Coding Conventions | .9. | Ensures a consistent coding style over time. |
Data Guarantees | .11. | Ensures end-users can enforce data contracts reliably. |
Data Guards | .12. | Ensures end-users and maintainers can build data guarantees reliably. |
Documentation | .1. | Helps end-users and the maintainers understand the what, the how, and the why. |
Errors | .2. | Ensures our code handles failure in a consistent, production-friendly manner. |
Functions | .8. | Ensures consistent behaviour from our public module API (and our internal API too). |
Naming Conventions | .3. | Ensures a consistent and tidier public module API (and our internal API too). |
Package Management | .4. | Ensures a consistent approach to packages over time. |
Protocols & Extensions | .10. | Ensures a consistent approach to extending types. |
Smart Constructors | .14. | Ensures our types really are safe types. |
Types | .6. | Ensures our types make for great building blocks. |
Type Guarantees | .13. | Ensures end-users and maintainers can enforce type contracts reliably. |
Type Guards | .7. | Ensures end-users have the type guards they need when they need them. |
Unit Tests | .5. | Ensures we ship less bugs and regressions. |
Here they are, listed by ID order too:
Category | ID | Description |
---|---|---|
Documentation | .1. | Helps end-users and the maintainers understand the what, the how, and the why. |
Errors | .2. | Ensures our code handles failure in a consistent, production-friendly manner. |
Naming Conventions | .3. | Ensures a consistent and tidier public module API (and our internal API too). |
Package Management | .4. | Ensures a consistent approach to packages over time. |
Unit Tests | .5. | Ensures we ship less bugs and regressions. |
Types | .6. | Ensures our types make for great building blocks. |
Type Guards | .7. | Ensures end-users have the type guards they need when they need them. |
Functions | .8. | Ensures consistent behaviour from our public module API (and our internal API too). |
Coding Conventions | .9. | Ensures a consistent coding style over time. |
Protocols & Extensions | .10. | Ensures a consistent approach to extending types. |
Data Guarantees | .11. | Ensures end-users can enforce data contracts reliably. |
Data Guards | .12. | Ensures end-users and maintainers can build data guarantees reliably. |
Type Guarantees | .13. | Ensures end-users and maintainers can enforce type contracts reliably. |
Smart Constructors | .14. | Ensures our types really are safe types. |
Coding standards must not exist for the sake of it. Each critera must address an issue in one (or more) of these areas:
Area | Impact |
---|---|
Adoption | These issues make it harder for people to use our projects in their own work. |
Contributions | These issues make it harder for people to contribute to our projects. |
Correctness | These issues make it harder to write code that works as intended. |
Governance | These issues make it harder to run the project. |
Project Maintenance | These issues make it harder to keep code up-to-date. |
Robustness | These issues make it harder to write code that copes with the unexpected or unintended. |
Security | These issues lead to breaches in data or unauthorised actions. |
Testability | These issues make it harder to provide meaningful tests. |
Priority | ID | Category | Criteria | Impacts |
---|---|---|---|---|
Key | 1.2.1 | Errors | Every function that has error conditions must accept an OnError handler. |
Adoption, Robustness |
Key | 1.2.2 | Errors | Only throw AppError s. |
Adoption, Robustness |
Key | 1.3.1 | Naming Conventions | All names must be racially-neutral. | Adoption |
Key | 1.4.1 | Package Management | Do not ship any code that isn't for production use. | Project Maintenance, Security |
Key | 1.5.1 | Unit Tests | All code must have 100% code coverage. | Adoption, Contributions, Correctness, Project Maintenance, Robustness |
Key | 1.6.1 | Types | All instantiable types must have a smart constructor. | Robustness |
Key | 1.6.2 | Types | Every instantiable type must have a type guard. | Adoption, Robustness, Testability |
Key | 1.6.3 | Types | Every instantiable type must have a type guarantee. | Adoption, Robustness, Testability |
Priority | ID | Category | Criteria | Impacts |
---|---|---|---|---|
Major | 2.3.1 | Naming Conventions | All functions and methods that return a function must be called buildXXX() . |
Adoption |
Major | 2.3.2 | Naming Conventions | All smart constructors must be prefixed with makeXXX() . |
Adoption |
Major | 2.3.3 | Naming Conventions | All type guards must be prefixed with isXXX() . |
Adoption |
Major | 2.3.4 | Naming Conventions | All type guarantees must be prefixed with mustBeXXX() . |
Adoption |
Major | 2.4.1 | Package Management | Export the entire public API from the API's top-level index file. | Adoption, Project Maintenance |
Major | 2.5.1 | Unit Tests | Use mocks as a last resort. | Correctness, Project Maintenance, Robustness |
Major | 2.6.1 | Types | All base classes must have a protected constructor. |
Robustness, Project Maintenance |
Major | 2.6.2 | Types | All generic types must provide an AnyXXX type. |
Adoption, Robustness |
Major | 2.6.3 | Types | All public constructors must be smart constructors. | Adoption, Robustness |
Major | 2.7.1 | Type Guards | Type guards must not accept the any type. Use unknown instead. |
Robustness |
Major | 2.8.1 | Functions | All function signatures must follow the same pattern. | Adoption, Correctness, Robustness, Testability |
Major | 2.8.2 | Functions | Functions should use dependency injection. | Adoption, Testability |
Major | 2.8.3 | Functions | Every mandatory dependency must be a named function parameter. | Correctness |
Major | 2.8.4 | Functions | Every user-supplied input must be a named parameter. | Adoption, Correctness |
Major | 2.8.5 | Functions | Avoid optional user-supplied inputs. | Adoption, Project Maintenance, Testability |
Major | 2.8.6 | Functions | User-supplied options must be a single options parameter. | Project Maintenance |
Major | 2.8.7 | Functions | Every property of the user-supplied options parameter must be optional. | Project Maintenance |
Major | 2.8.8 | Functions | Ever user-supplied option must have a default value. | Adoption, Testability |
Major | 2.8.9 | Functions | Functional options must be captured as a rest parameter. | Adoption |
Major | 2.8.10 | Functions | Define DEFAULT_OPTIONS for every function that cannot meet 2.8.7. |
|
Major | 2.10.1 | Protocols and Extensions | Every protocol interface must define an implementsXXX() method. |
Adoption, Robustness |
Priority | ID | Category | Criteria | Impacts |
---|---|---|---|---|
Minor | 3.1.1 | Documentation | Every exported item must have a docblock. | Adoption, Project Maintenance |
Minor | 3.1.2 | Documentation | Docblocks must begin with the name of the item they document. | Adoption |
Minor | 3.1.3 | Documentation | Docblocks must use whole sentences. | Adoption |
Minor | 3.1.4 | Documentation | Docblocks must use Typedoc tags. | Adoption, Contributions, Project Maintenance |
Minor | 3.1.5 | Documentation | Write docblocks for overridden methods. | Adoption |
Minor | 3.1.6 | Documentation | Write docblocks for methods inherited from interfaces. | Adoption |
Minor | 3.3.1 | Naming Conventions | Every function or method must start with <verb><noun> . |
Adoption |
Minor | 3.3.2 | Naming Conventions | Use camelCase for all function names. | Adoption, Contributions |
Minor | 3.3.3 | Naming Conventions | Use camelCase for all variable names. | Adoption, Contributions |
Minor | 3.3.4 | Naming Conventions | Use SCREAMING_SNAKE_CASE for all constants. | Adoption, Contributions |
Minor | 3.3.5 | Naming Conventions | Use PascalCase for all interface names. | Adoption, Contributions |
Minor | 3.3.6 | Naming Conventions | Use camelCase for all interface property names. | Adoption, Contributions |
Minor | 3.3.7 | Naming Conventions | Use PascalCase for all class names. | Adoption, Contributions |
Minor | 3.3.8 | Naming Conventions | Use camelCase for all class property names. | Adoption, Contributions |
Minor | 3.3.9 | Naming Conventions | Prefix private and protected class attributes with an underscore. | Adoption, Contributions |
Minor | 3.3.10 | Naming Conventions | All Error class names must end with Error . |
Adoption, Contributions |
Minor | 3.3.11 | Naming Conventions | All user-supplied option classes/interface names must end with Options . |
Adoption, Contributions |
Minor | 3.3.12 | Naming Conventions | Do not name anything blacklist or whitelist . |
Adoption |
Minor | 3.3.13 | Naming Conventions | All default options must be called XXX_DEFAULT_OPTIONS . |
Adoption, Project Maintenance |
Minor | 3.3.14 | Naming Conventions | All default values must be called DEFAULT_XXX . |
Adoption |
Minor | 3.4.1 | Package Management | Every module folder must have an index file. | Project Maintenance |
Minor | 3.4.2 | Package Management | Index files must only export the public API. | Adoption, Project Maintenance |
Minor | 3.4.3 | Package Management | Put each safe type into its own folder. | Project Maintenance |
Minor | 3.4.4 | Package Management | Put exported classes in their own files. | Contributions, Project Maintenance |
Minor | 3.4.5 | Package Management | Put exported functions in their own files. | Contributions, Project Maintenance |
Minor | 3.4.6 | Package Management | Put exported types in their own files. | Contributions, Project Maintenance |
Minor | 3.4.7 | Package Management | Put exported default values in their own file. | Contributions, Project Maintenance |
Minor | 3.5.1 | Unit Tests | Put fixtures into a folder called _fixtures . |
Project Maintenance |
Minor | 3.6.1 | Types | Every interface that is meant to be implemented must define an implementsXXX() method. |
Robustness |
Minor | 3.6.2 | Types | Do not create static factory methods. | Adoption, Project Maintenance |
Minor | 3.7.1 | Type Guards | Every type guard must have a unit test that proves it is a type predicate. | Robustness |
Minor | 3.8.1 | Functions | Create a type for your function's user-supplied options. | Adoption |
Minor | 3.8.2 | Functions | Limit user-supplied options to optional dependencies. | Correctness, Project Maintenance, Testability |
Minor | 3.8.3 | Functions | Use DEFAULT_DATA_PATH for all optional data path parameters. |
Adoption |