nostr-tools
There are many reasons to build on Nostr, but to me the main one is the fact that we don't have a central codebase anywhere.
If nostr:nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gprfmhxue69uhhq7tjv9kkjepwve5kzar2v9nzucm0d5hszxmhwden5te0wfjkccte9emk2um5v4exucn5vvhxxmmd9us2xuyp had said "this is nostr and here is my library you all should use", I would have never done anything in Nostr.
Amethyst, Primal, Coracle, NoStrudel, and Damus and many other apps before and after us are all built from scratch.
No vendor lock in. No centralized dependencies. No core choke point to kill it all together.
True decentralization is hard. But it is worth every penny.
Discussion
Nowhere near as used as you think it is. It's a good starting tool, but as soon as you get serious you will need to rebuild from scratch.
Then there is no concrete protocol, because everyone does different things. Nostr is in need of standardization to scale further, imho.
The point is that there is no need for a single implementation in order for current apps to interoperate. They are doing great even not sharing any codebase.
We can agree to differ here. I'll put it to you that the protocol (NIP-01) is under specified, because it doesnt define things like stringify, so unless everyone goes with nostr-tools you'll have different implementations doing different things, especially in different languages. Little bits of technical debt add up ...
I can tell you that each language's stringify is matching quite well to what nip01 describes, which just follows the json spec. JavaScript, Kotin, go, swift, rust, C, and even php are matching.
What else would you like defined that isn't defined anywhere else?
nostr:npub1melv683fw6n2mvhl5h6dhqd8mqfv3wmxnz4qph83ua4dk4006ezsrt5c24 is actually right on this.
There are multiple possible strings for the same JSON because each string in the JSON can be codified in multiple ways and that's because each character can be written in different ways in a string in JavaScript.
The issue is that stringification is used to compute hashes, so it's crucial that everyone gets the same result because everyone needs to get the same hash.
In practice, the different main native implementations of JSON do lead to the same result (every time? most of the time?), so this hasn't been a practical problem, but NIP-01 is underspecified.
A proper specification can be written to be back-compatible by mandating that which currently just happens to be true in different implementations, but required to none.
On everything else we can experiment, having different clients behaving differently and live with the mess that Nostr is and is supposed to be, but hashes have to be consistent.
Note that even if Nostr had an official reference implementation this wouldn't actually solve the issue because not every detail of an implementation, not even the official reference one, is part of a protocol.
But at this stage we might still be fine with what we have, given that, although it's been around for a while now, Nostr is still somewhat experimental.
I concur that it is not fully documented, but it's close enough and simple trial and error finds the correct order
I see the opposite problem.
When I first discovered nostr, about a year after the protocol was initially specified, I imagined it as a general message transport protocol. Then, fiatjaf said, and I may be paraphrasing, "nostr is not a general message transport protocol". So I decided okay, where is this going. I like the living network, organic evolution, minds discovering possibilities and making things real. But I also like constraints, a bucket to ultimately fill, a goal, "it works now, have fun."
What I see now is everyone trying to fit their use case into nostr, and an explosion of NIPs, a situation that looks very http-esque. There are nips for single client use cases, and then generalized nips for general use cases so ambiguous that they will confuse interoperable clients. Now we are even at the point that we have different canonical registries of approved nips and permissionless nip implementation. It looks like not a protocol at all, just a guideline for what ultimately may be an unmaintainable mess, ripe for conquest by those who seek to control information distribution.
I think a good balance of "this is what it is for" and "do what you want with it" is desirable, and I'm seeing that, but in an unstable equilibrium, and I fully expect to be disappointed by the future with regard to this thing we have.
I'm building something using python, and I'm running into trouble with python libs for nostr so much that I'm considering just using nak as a system library and making all my calls to it. Seems fucky so I've been putting off work on this particular project while I overanalyze. Would you recommend such a design choice?
Just build from scratch. It's not that hard.
I've got a lot going on in my life, and building on nostr is not my top priority. I like to leverage the FOSS benefit of building together, on top of each other's work in a distributed way, to expedite making our visions real. "Maximum impact with minimum effort" is my mantra wrt building software tools.