# F# library development guidelines

**URL:** <https://forums.fsharp.org/t/f-library-development-guidelines/1738>\
**Category:** General\
**Created:** [July 17, 2021, 8:21pm UTC](https://forums.fsharp.org/t/f-library-development-guidelines/1738 "2021-07-17T20:21:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ianmackenzie](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ianmackenzie/32/951_2.png) [@ianmackenzie](https://forums.fsharp.org/u/ianmackenzie)\
**Post date:** [July 17, 2021, 8:21pm UTC](https://forums.fsharp.org/t/f-library-development-guidelines/1738/1 "2021-07-17T20:21:38Z")

</div>

Are there any good tutorials/guidelines for developing F# libraries? I’m considering porting some of my open-source Elm packages such as [`elm-geometry`](https://github.com/ianmackenzie/elm-geometry) to F#, but had a few questions like:

- What are the currently recommended ways to set up a library project? Some combination of `dotnet new`, Paket, FAKE…?
- Are there good ways to publish for multiple .NET versions? I’d love to just stick to .NET 5 (or 6 once it’s out), but I’ll likely have to at least attempt to also build for .NET Framework 4.7. Is this possible using multiple build targets in FAKE or something?
- Are the [Microsoft F# component design guidelines](https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/component-design-guidelines) the best general source for library design best practices or are there others I should be checking out?
- One specific API design question - is it considered best practice to expose functions as both module-level functions and member methods on types? (So that you could for example write both `Vector3d.plus v1 v2` or `v1.Plus(v2)`…)

I hope these questions make sense - I’m still trying to orient myself to the F# ecosystem in general so I may have made some bad assumptions.

---

<div class="post-metadata">

**Author:** ![charlesroddie](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/charlesroddie/32/45_2.png) [@charlesroddie](https://forums.fsharp.org/u/charlesroddie)\
**Post date:** [July 17, 2021, 8:42pm UTC](https://forums.fsharp.org/t/f-library-development-guidelines/1738/2 "2021-07-17T20:42:34Z")

</div>

1. Simplest is using standard dotnet packaging which you get with `dotnet new` or new projects from IDEs.
2. Target netstandard2.0. It gives a very good set of APIs and has very wide compatibility, including netframework4.7.
3. That’s a very good guide!
4. For the plus operation in particular I would define `static member (+) (x:Vector3D,y:Vector3D)` to allow for use of the addition operator. (.Net will have static interface methods which may in the future shift the preferred approach to `interface IAddable<Vector3D> with static member Add(x,y) = ...`.) In general it depends on the method. I use functions or instance methods depending on which is more natural and `v1.Plus(v2)` is an example where I wouldn’t use the instance method as the asymmetry doesn’t fit the operation. For functions, you can implement curried or tupled functions - `Plus v1 v2` or `Plus(v1,v2)` - but note that if you use curried functions you restrict consumption to F#. I personally use curried functions only if 1. consumers will be F# only, and 2. there is a natural curried order with one input that is more varying than the other.

---

<div class="post-metadata">

**Author:** ![ianmackenzie](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/ianmackenzie/32/951_2.png) [@ianmackenzie](https://forums.fsharp.org/u/ianmackenzie)\
**Post date:** [July 18, 2021, 2:12am UTC](https://forums.fsharp.org/t/f-library-development-guidelines/1738/3 "2021-07-18T02:12:23Z")

</div>

Thanks @charlesroddie, that’s very helpful! Targeting `netstandard2.0` does seem like good advice. And good point on adding a `+` operator - I should have picked a better example 🙂

I’ll probably start with an F#-centric API, and then look at improving support for C# etc. if there’s a need.
