These are the existing, non-codified community practices that are currently propagated through informal agreement. We might remove some of them at one point, and enforce some others. Right now, they're just recommendations for ease of newcomers.
Capitalized file names (aka first letter upper-cased).
Justification: Module names can only be capitalized. Newcomers often ask how a file maps to a module, and why
draw.re maps to the module
Draw, and sometimes try to refer to a module through uncapitalized identifiers. Using
Draw.re makes this mapping more straightforward. It also helps certain file names that'd be awkward in uncapitalized form:
This is generated by the build system (at least for the JS workflow) and you should not have to manually edit it. Don't check it into the repo.
.merlin is for Merlin to understand the project layout and to provide editor tooling. The file contains absolute paths, which are also not cross-platform (e.g. Windows paths are different).
Try not to have too many nested folders. Keep your project flat, and have fewer files (reminder: you can use nested modules).
Justification: The file system is a tree, but your code's dependencies are a graph. Because of that, any file & folder organization is usually imperfect. While it's still valuable to group related files together in a folder, the time wasted debating & getting decision paralysis over these far outweight their benefits. We'll always recommend you to Get Work Done instead of debating about these issues.
Keep them to a minimum.
Justification: A compiled, statically typed language cannot model its dependencies easily by muddling along like in a dynamic language, especially when we're still piggy-backing on NPM/Yarn (to reduce learning overhead in the medium-term), both not made with Reason/BuckleScript in mind. Keeping dependencies simple & lean helps reduce possibility of conflicts (e.g. two diamond dependencies, or clashing interfaces).
Model third-party code as
Justification: you should spiritually treat them as implementation details that might be swapped out one day.
Have them. Spend more effort making them great (examples, pitfalls) and professional rather than just fancy-looking. Do use examples, and avoid using names such as
bar. There's always more concrete names (it's an example, no need to be abstract/generalized just yet. The API docs will do this plentily). For blog posts, don't repeat the docs themselves, describe the transition from old to new, and why (e.g. "it was a component, now it's a function, because ...").
Justification: It's hard for newcomers to distinguish between a simple/decent library and one that's fancy-looking. For the sake of the community, don't try too hard to one-up each other's libraries. Do spread the words, but use your judgement too.
PPX & Other Meta-tools
Keep them to a minimum. PPX, unless used in renown cases (printer, accessors and serializer/deserializer generation), can cause big learning churn for newcomers; on top of the syntax, semantics, types, build tool & FFI that they already have to learn, learning per-library custom transformations of the code is an extra step. More invasive macros makes the code itself less semantically meaningful too, since the essence would be hiding somewhere else.
Don't abuse overly fancy features. Do leave some breathing room for future APIs but don't over-architect things.
Justification: Simple code helps newcomers understand and potentially contribute to your code. Contributing is the best way for them to learn. The extra help you receive might also surpass the gain of using a slightly more clever language trick. But do try new language tricks in some of more casual projects! You might discover new ways of architecting code.
If it's a wrapper for a JS library, don't publish the JS artifacts. If it's a legit library, publish the artifacts in lib/js if you think JS consumers might use it. This is especially the case when you gradually convert a JS lib to Reason + BuckleScript while not breaking existing JS consumers.
Do put the keywords
"bucklescript" in your package.json
keywords field. This allows us to find the library much more easily for future purposes.
Justification: Be nice to JS consumers of your library. They're your future Reasoners.