I've been working on [Relay](https://relay.md) for about a year now, and I've been using the Obsidian API heavily. Here are the parts of Obsidian's Plugin API that are making paid plugins a pain to build. # Identity Relay is building collaboration for Obsidian. For this, we had to build a control plane for authentication and authorization. We use a mix of identity providers, but they all feel a bit gross. People trust Obsidian, but frequently have complains about Google, or other providers that we support. The dream here is that Obsidian operate as an oauth2 provider. Users could opt-in to share their name/email/device name with a plugin, and then just not really need to think about login. The client-side could be a lot better supported too -- we had to monkeypatch the webviewer to make sure that login links opened in users' default browser so that they were likely to already be signed in to the account. In addition, Obsidian could leverage its platform position to store the login credentials... which brings me too... # Secrets Storage > [!NOTE] It's happening! > The Obsidian team has been working on this feature. I provided the following feedback in the insider's discord: > The current interface seems designed for **user-provided secrets** (API keys), where the user enters a value they already know. I'd like to store **application-acquired secrets** (e.g., tokens from an OAuth flow) where the user authenticates but never directly handles the credential. > For this use case, exposing the secret by name to users (or other plugins) isn't ideal. A few additions would help: > > - **Plugin-scoped namespace**: secrets isolated to the plugin that created them > - **Write-only / opaque flag**: user can see *that* a secret exists (and delete it), but can't read the value > > This would let plugins use the encryption primitive for delegated credentials without implying users should copy or share them. The Obsidian plugin ecosystem has a little bit of vetting on the first app submission, but after that it is largely trust based. There are a few options for storing secrets (indexeddb, local storage, cookies), but they are unencrypted on disk. It would be great to build some platform keychain support into the electron app. # Trusted Plugins + Community Repository Obsidian is in a bit of a crunch reviewing plugins for their internal plugin store. People are making a lot more plugins with the help of LLMs and it is a huge burden to review them all. At the same time, the plugins in the marketplace are all only ever reviewed once! This is a liability for Obsidian. Instead, I think they would benefit from following something similar to Arch Linux with the Official Repositories and then the Arch User Repository (Firefox has a similar setup). The Official Repository might even include things like legal contracts with plugin providers, while the User Repository would be able to contain anything. Win/win. # Smoother plugin updates The distribution of Relay plugin versions has users on the very first public version of Relay. We wanted to make this smoother, but eventually realized that Obsidian has language in the developer policies to avoid doing automatic update. This is a bummer because it makes developing a service much harder. # Payments This one is a challenge for the Obsidian folks -- according to @kepano this is against the terms of being in the app store (or else maybe they would need to pay 30% on top of their cut). Still, I think there are a lot of plugin developers who would be excited to turn on payments. Integrating with a payment process is a lot of work that would need to be done over and over again. # Indexeddb namespacing This is a small thing, but it would be nice to feel a bit more "namespaced" when accessing things. A simple wrapper that put the app-id and plugin-id as a prefix would go a long way. # Interoperable CRDT API We're building what we feel are the missing pieces within Obsidian that can make it the ideal knowledge management tool for businesses. As part of this, we built out collaboration. In our opinion, building collaboration requires CRDTs for a good user experience. CRDTs need some way to be persisted, and they also need identity (who make what edits). The ideal API here would be to have: * A standardized file format (file-over-app) for CRDT files. I think this should either be per-user sqlite database or a "companion file" like `my-note.md.crdt` * A way to interact with the crdt library API (we use yjs) that abstracts over the persistence and includes a *user mapping* for each ydoc so that edits can be attributed to user IDs (again, the need for identity here). * An interface for the document text (ytext) * An interface for the frontmatter (jmap) Up until now, our focus has been on getting collaboration working *at all*, but file-over-app principles and end-to-end encryption are deeply important to us. I've started exploring file format for what a standard file format for collaboration data might look like. # Memory friendly hashing API We run a sha256 has over file contents in order to facilitate file syncing. As far as I can tell, it is impossible to stream TFile objects through a hashing function, so the entire file has to be loaded into memory. This can be a challenge on smaller devices and requires building some kind of queuing system that can do background work without loading too many files into memory at a time. # Streaming write API Similar to the memory-friendly hashing issue, writing large files through the Obsidian API currently requires loading the entire content into memory before calling `vault.modify()` or `vault.create()`. This becomes problematic when: - Syncing large files from external sources - Processing and transforming data that exceeds reasonable memory limits - Building import/export features for bulk operations - Implementing efficient file compression or encryption The current API forces us to either: 1. Load everything into memory (risking crashes on mobile/low-memory devices) 2. Write directly to the filesystem (bypassing Obsidian's file watching and potentially causing sync conflicts) 3. Chunk files artificially (creating a poor user experience) An ideal streaming write API would: - Accept a readable stream or async iterator as input - Handle backpressure appropriately - Trigger file watchers only once the write is complete - Provide progress callbacks for long operations - Maintain atomicity (write to temp file, then rename) This would enable more robust plugin architectures that can handle files of any size without memory constraints, making Obsidian more suitable for professional workflows that involve large datasets, media files, or bulk operations.