Skip to content

Style guidelines

  • Where possible keep lines to 80 characters. Don’t try too hard if it makes the code uglier, though.
  • Write a README. It should include, at minimum:
    1. How to set up the codebase
    2. How to run it locally on a developer machine
    3. How to test it (e.g. how to run the tests locally)
    4. How to deploy it.

We have a de facto Ruby style, and if you follow Shopify’s Ruby Style Guide you’ll be pretty much there.

We use Rubocop and overcommit with our own Rubocop configuration that leans heavily on Shopify’s configuration.

We don’t have a central place for our Rubocop and overcommit configuration right now, but you can pull it from another project, or from this handbook. The .rubocop.yml looks something like this:

# On fresh projects this is easier, on existing projects we might skip this
require: rubocop-rails
inherit_gem:
rubocop-shopify: rubocop.yml
# Ruby 3 is gonna make this default anyway...in the mean time magic comments
# are not our jam.
Style/FrozenStringLiteralComment:
Enabled: false
# Not really a fan of trailing commas, sorry Shopify.
Style/TrailingCommaInHashLiteral:
Enabled: false
# Ditto above
Style/TrailingCommaInArrayLiteral:
Enabled: false
# But Ruby is beautiful without them!
Style/MethodCallWithArgsParentheses:
Enabled: false
# The way rubocop autocorrects this is v. ugly; a hard line break and no
# indentation.
Layout/LineLength:
Enabled: false
# We use {} for multi line blocks in tests
Style/BlockDelimiters:
Exclude:
- 'spec/**/*_spec.rb'
# Support 'redirect and return if y'
# See <https://github.com/rubocop/rubocop/issues/1288>
Style/AndOr:
EnforcedStyle: conditionals
AllCops:
# Generally new cops are worth enabling especially from rubocop-rails
NewCops: enable
# Don't cop binstubs
Exclude:
- 'bin/*'

And an .overcommit.yml that looks something like this:

# Overcommit runs hooks automatically when committing, pushing etc.
# Don't bother with any commit message checks
CommitMsg:
ALL:
enabled: false
PreCommit:
# Enable Rubocop
RuboCop:
enabled: true
on_warn: fail # Treat all warnings as failures
# Use bundled rubocop for consistency
command: ['bundle', 'exec', 'rubocop']
# Check for leftover merge conflicts
MergeConflicts:
enabled: true
description: 'Check for merge conflicts'
quiet: true
required_executable: 'grep'
flags: ['-IHn', "^<<<<<<<[ \t]"]
# Do nothing post-checkout
PostCheckout:
ALL:
enabled: false

This requires adding rubocop, rubocop-shopify and overcommit to your Gemfile. They should all be set to require: false.

We’re considering adopting rubocop-rspec and a form of The RSpec Style Guide. It broadly lines up with our de facto style, but there’s definitely improvements we could make.

We don’t have a particular style for JavaScript right now. Use JavaScript Standard Style to resolve bike-shed debates. Specifically semistandard because we use semicolons to terminate expressions.

Remember documentation is something we don’t priorities (see Priorities) but we still write plenty of documentation! In particular:

  • Code repository documentation (e.g. a README) should be limited to information that helps you (a developer) develop that project.
  • Project runbooks should contain information that helps you run (e.g. manage, maintain, support) a live project.

If you’re not sure whether some documentation belongs in the repository or the project runbook, ask!