{"id":13562733,"url":"https://github.com/alexandru/scala-best-practices","last_synced_at":"2025-04-13T13:25:28.411Z","repository":{"id":22145847,"uuid":"25477005","full_name":"alexandru/scala-best-practices","owner":"alexandru","description":"A collection of Scala best practices","archived":false,"fork":false,"pushed_at":"2022-11-09T16:59:04.000Z","size":184,"stargazers_count":4385,"open_issues_count":22,"forks_count":623,"subscribers_count":352,"default_branch":"master","last_synced_at":"2025-04-06T10:08:22.896Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexandru.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"patreon":"alexelcu"}},"created_at":"2014-10-20T17:06:25.000Z","updated_at":"2025-04-01T02:38:31.000Z","dependencies_parsed_at":"2023-01-11T21:30:07.172Z","dependency_job_id":null,"html_url":"https://github.com/alexandru/scala-best-practices","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandru%2Fscala-best-practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandru%2Fscala-best-practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandru%2Fscala-best-practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandru%2Fscala-best-practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexandru","download_url":"https://codeload.github.com/alexandru/scala-best-practices/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248719308,"owners_count":21150730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:01:11.756Z","updated_at":"2025-04-13T13:25:28.386Z","avatar_url":"https://github.com/alexandru.png","language":null,"funding_links":["https://patreon.com/alexelcu"],"categories":["Others","Best Practice ##","Programming Languages"],"sub_categories":["Version 1.x ###","Scala"],"readme":"# Scala Best Practices\n\n[![Join the chat at https://gitter.im/alexandru/scala-best-practices](https://badges.gitter.im/alexandru/scala-best-practices.svg)](https://gitter.im/alexandru/scala-best-practices?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n\u003cimg src=\"https://raw.githubusercontent.com/monifu/scala-best-practices/master/assets/scala-logo-256.png\"  align=\"right\" width=\"100\" height=\"100\" /\u003e\n\nA collection of best practices, friendly to people that want to\ncontribute.\n\n- Version: `1.2`\n- Updated at: `2016-06-08`\n\n## Table of Contents\n\n- [0. Preface](sections/0-preface.md)\n  - [0.1 MUST NOT follow advice blindly](sections/0-preface.md#01-must-not-follow-advice-blindly)\n\n- [1. Hygienic Rules](sections/1-hygienic-rules.md)\n  - [1.1. SHOULD enforce a reasonable line length](sections/1-hygienic-rules.md#11-should-enforce-a-reasonable-line-length)\n  - [1.2. MUST NOT rely on a SBT or IDE plugin to do the formatting for you](sections/1-hygienic-rules.md#12-must-not-rely-on-a-sbt-or-ide-plugin-to-do-the-formatting-for-you)\n  - [1.3. SHOULD break long functions](sections/1-hygienic-rules.md#13-should-break-long-functions)\n  - [1.4. MUST NOT introduce spelling errors in names and comments](sections/1-hygienic-rules.md#14-must-not-introduce-spelling-errors-in-names-and-comments)\n  - [1.5. Names MUST be meaningful](sections/1-hygienic-rules.md#15-names-must-be-meaningful)\n\n- [2. Language Rules](sections/2-language-rules.md)\n  - [2.1. MUST NOT use \"return\"](sections/2-language-rules.md#21-must-not-use-return)\n  - [2.2. SHOULD use immutable data structures](sections/2-language-rules.md#22-should-use-immutable-data-structures)\n  - [2.3. SHOULD NOT update a \"var\" using loops or conditions](sections/2-language-rules.md#23-should-not-update-a-var-using-loops-or-conditions)\n  - [2.4. SHOULD NOT define useless traits](sections/2-language-rules.md#24-should-not-define-useless-traits)\n  - [2.5. MUST NOT use \"var\" inside a case class](sections/2-language-rules.md#25-must-not-use-var-inside-a-case-class)\n  - [2.6. SHOULD NOT declare abstract \"var\" members](sections/2-language-rules.md#26-should-not-declare-abstract-var-members)\n  - [2.7. MUST NOT throw exceptions for validations of user input or flow control](sections/2-language-rules.md#27-must-not-throw-exceptions-for-validations-of-user-input-or-flow-control)\n  - [2.8. MUST NOT catch Throwable](sections/2-language-rules.md#28-must-not-catch-throwable-when-catching-exceptions)\n  - [2.9. MUST NOT use \"null\"](sections/2-language-rules.md#29-must-not-use-null)\n  - [2.10. MUST NOT use \"Option.get\"](sections/2-language-rules.md#210-must-not-use-optionget)\n  - [2.11. MUST NOT use Java's Date or Calendar, instead use `java.time` (JSR-310)](sections/2-language-rules.md#211-must-not-use-javas-date-or-calendar-instead-use-javatime-jsr-310)\n  - [2.12. SHOULD NOT use Any or AnyRef or isInstanceOf / asInstanceOf](sections/2-language-rules.md#212-should-not-use-any-or-anyref-or-isinstanceof--asinstanceof)\n  - [2.13. MUST serialize dates as either Unix Timestamp or ISO 8601](sections/2-language-rules.md#213-must-serialize-dates-as-either-unix-timestamp-or-as-iso-8601)\n  - [2.14. MUST NOT use magic values](sections/2-language-rules.md#214-must-not-use-magic-values)\n  - [2.15. SHOULD NOT use \"var\" as shared state](sections/2-language-rules.md#215-should-not-use-var-as-shared-state)\n  - [2.16. Public functions SHOULD have an explicit return type](sections/2-language-rules.md#216-public-functions-should-have-an-explicit-return-type)\n  - [2.17. SHOULD NOT define case classes nested in other classes](sections/2-language-rules.md#217-should-not-define-case-classes-nested-in-other-classes)\n  - [2.18. MUST NOT include classes, traits and objects inside package objects](sections/2-language-rules.md#218-must-not-include-classes-traits-and-objects-inside-package-objects)\n  - [2.19. SHOULD use head/tail and init/last decomposition only if they can be done in constant time and memory](sections/2-language-rules.md#219-should-use-head-tail-and-init-last-decomposition-only-if-they-can-be-done-in-constant-time-and-memory)\n  - [2.20. MUST NOT use `Seq.head`](sections/2-language-rules.md#220-must-not-use-seqhead)\n  - [2.21. Case classes SHOULD be final](sections/2-language-rules.md#221-case-classes-should-be-final)\n  - [2.22. SHOULD NOT use `scala.App`](sections/2-language-rules.md#222-should-not-use-scalaapp)\n\n- [3. Application Architecture](sections/3-architecture.md)\n  - [3.1. SHOULD NOT use the Cake pattern](sections/3-architecture.md#31-should-not-use-the-cake-pattern)\n  - [3.2. MUST NOT put things in Play's Global](sections/3-architecture.md#32-must-not-put-things-in-plays-global)\n  - [3.3. SHOULD NOT apply optimizations without profiling](sections/3-architecture.md#33-should-not-apply-optimizations-without-profiling)\n  - [3.4. SHOULD be mindful of the garbage collector](sections/3-architecture.md#34-should-be-mindful-of-the-garbage-collector)\n  - [3.5. MUST NOT use parameterless ConfigFactory.load() or access a Config object directly](sections/3-architecture.md#35-must-not-use-parameterless-configfactoryload-or-access-a-config-object-directly)\n\n- [4. Concurrency and Parallelism](sections/4-concurrency-parallelism.md)\n  - [4.1. SHOULD avoid concurrency like the plague it is](sections/4-concurrency-parallelism.md#41-should-avoid-concurrency-like-the-plague-it-is)\n  - [4.2. SHOULD use appropriate abstractions only where suitable](sections/4-concurrency-parallelism.md#42-should-use-appropriate-abstractions-only-where-suitable---future-actors-rx)\n  - [4.3. SHOULD NOT wrap purely CPU-bound operations in Futures](sections/4-concurrency-parallelism.md#43-should-not-wrap-purely-cpu-bound-operations-in-futures)\n  - [4.4. MUST use Scala's BlockContext on blocking I/O](sections/4-concurrency-parallelism.md#44-must-use-scalas-blockcontext-on-blocking-io)\n  - [4.5. SHOULD NOT block](sections/4-concurrency-parallelism.md#45-should-not-block)\n  - [4.6. SHOULD use a separate thread-pool for blocking I/O](sections/4-concurrency-parallelism.md#46-should-use-a-separate-thread-pool-for-blocking-io)\n  - [4.7. All public APIs SHOULD BE thread-safe](sections/4-concurrency-parallelism.md#47-all-public-apis-should-be-thread-safe)\n  - [4.8. SHOULD avoid contention on shared reads](sections/4-concurrency-parallelism.md#48-should-avoid-contention-on-shared-reads)\n  - [4.9. MUST provide a clearly defined and documented protocol for each component or actor that communicates over async boundaries](sections/4-concurrency-parallelism.md#49-must-provide-a-clearly-defined-and-documented-protocol-for-each-component-or-actor-that-communicates-over-async-boundaries)\n  - [4.10. SHOULD always prefer single producer scenarios](sections/4-concurrency-parallelism.md#410-should-always-prefer-single-producer-scenarios)\n  - [4.11. MUST NOT hard-code the thread-pool / execution context](sections/4-concurrency-parallelism.md#411-must-not-hardcode-the-thread-pool--execution-context)\n\n- [5. Akka Actors](sections/5-actors.md)\n  - [5.1. SHOULD evolve the state of actors only in response to messages received from the outside](sections/5-actors.md#51-should-evolve-the-state-of-actors-only-in-response-to-messages-received-from-the-outside)\n  - [5.2. SHOULD mutate state in actors only with \"context.become\"](sections/5-actors.md#52-should-mutate-state-in-actors-only-with-contextbecome)\n  - [5.3. MUST NOT leak the internal state of an actor in asynchronous closures](sections/5-actors.md#53-must-not-leak-the-internal-state-of-an-actor-in-asynchronous-closures)\n  - [5.4. SHOULD do back-pressure](sections/5-actors.md#54-should-do-back-pressure)\n  - [5.5. SHOULD NOT use Akka FSM](sections/5-actors.md#55-should-not-use-akka-fsm)\n\n---\n\n## Contribute\n\nOpen an issue to make suggestions, or create a pull request ;-)\n\n---\n\nCopyright \u0026copy; 2015-2016, Some Rights Reserved.\u003cbr /\u003e\nLicensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandru%2Fscala-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandru%2Fscala-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandru%2Fscala-best-practices/lists"}