Coming from Logseq, Outlines and Linked Mentions

Hi! I’ve been test-driving Silver Bullet for a few days now. As a regular Logseq user, I thought I’d add some initial thoughts in the hope it may be helpful feedback.

Things I immediately love

  • Self-hosted, dockerized, painless to get up and running
  • The simple underlying file structure (markdown files in a hierarchical directory structure)
  • Extendable and customizable beyond any other app (PlugOS concept)
  • PWA frontend is smooth and reliable
  • Offline mode is really exciting though I have not yet tested this feature. My hope is that I can self host in a home network, go out into the world adding notes, and return home to sync up.
  • The docs (nice work!)
  • The community seems pretty active and growing

Things I immediately miss from Logseq:

1. Outlines (Bulleted Lists)

Specifically, Logseq creates relationships/refs via nested outlines, which enable a highly efficient journal-based workflow.

If I’m editing a daily Journal, and I want to add some notes about a particular subject (page), all I need to do is reference that page in the top level of the outline, then add notes or tasks nested under that item.

For example, let’s say I have a 1on1 with someone named Swarna. Let’s say Swarna is part of a team “Dev Team”. Typically I will open 2 windows:

  1. The page for [[Swarna]] or the team they belong to [[Dev Team]]. On this team page, there are several queries to see previous discussion topics, tasks, and notes from all members of the team. This means I go to every meeting with all the most important active topics and tasks within that context.
  2. The daily journal (99% of intake is done exclusively in journals)
* [[Swarna]]
  * [ ] a new task I need to accomplish
  * [ ] #topic an open topic for discussion in future conversations with Swarna

In Logseq, all nested “blocks” are related to the link mention in the parent block. This is accomplished via path-refs property of a block (see full block schema here), which collects all the linked pages on this item, or on any of its parent items, up to and including the page it is added to.

Why is this an advantage? Because it allows me to add referenced content to a particular page without the need to leave my Journal. Because I don’t need to leave my journal, I can add content or tasks to multiple pages from the same journal, allowing me to context switch very quickly. The tool stays out of the way of the note intake. In addition, when you visit a specific page like the team page, the “Linked Mentions” equivalent function in Logseq displays all references to the page, and (since everything was added via journal) each update also shows the specific date when you added it. This would make Linked Mentions in SB much more powerful.

If I wanted to do this today in SB, it seems I have 2 options:

  1. I would need to add the [[Swarna]] link mention to each individual item. Then I would be able to query task where name =~ /swarna/ checking the name string property of the task.
  2. For each topic in my meeting, I would need to leave my Journal and visit the specific page for the active topic, add some notes, then go to a different page when topics change. I’m assuming this is how most people use SB.

SB attribute proposal – To solve this exclusively for an item object type, it would be great if it contained a similar attribute to path-refs which contained all the linked pages referenced by any parents (ideally these would be stored in hierarchical order so they can be used as a sort of breadcrumb). I found this concept of custom attribute extractors in your docs that appears promising, but I believe currently we only have access to the text of this single item, and therefore can not use this approach to collect the link refs of parent items. Is that correct?

In my view, there should also be a way to nest content (not only items and tasks) under a link ref, so the entire chunk of linked content would show up under the existing “Linked Mentions”.

2. Editing Live Content

Currently in SB, if I create a template to render tasks from other pages, those tasks are not editable in place (for example to alter the deadline or to tick the checkbox). Instead I need to go back to the source page where the task was originally added to make any changes.

Is this an intentional decision? Shouldn’t this content be editable and update the origin unless it has been “baked” onto the page?

This goes for Linked Mentions, and any custom template.

3. The Search

In Logseq all search is rolled up into a single UI which includes grouped results for pages, blocks (specific content), commands, recents, etc. This is a relatively minor critique.


That’s all for now. I hope this was helpful. I look forward to continuing to adopt this great tool, and would love to contribute in the future.

2 Likes

First of all, thanks for this write up. It’s great to get the Logseq perspective. I’ve played around with it a bit, saw some videos, but never really used it day to day.

I’ll spend some more time interpreting exactly how things work in Logseq as you describe and the workflows it enabled and indeed how that could translate to a tool like SB. Without really thinking about it yet, and not fully appreciating your ideas and suggestions here: I think it’s super interesting to look at how you’d do something in Logseq, then see if you could do that same thing in SB, or if there’s a more natural “SB solution” that achieves simillar results. This is a bit of a mental exercise, however (and I don’t have the brain cycles for it at the very moment :wink: ).

Hey @zef , I really appreciate your reply, and your great work and commitment to the project!

I’m happy to answer any Logseq questions you have.

I think it’s super interesting to look at how you’d do something in Logseq, then see if you could do that same thing in SB, or if there’s a more natural “SB solution” that achieves simillar results.

What is interesting about Logseq and similar tools is that they attempt to remain unopinionated enough to accommodate multiple workflows, but that flexibility is a double edged sword. It also brings difficulty in onboarding new users, challenges in documentation, and maintaining support for all the common workflows as new features are introduced. So I can completely understand your desire to default to a more natural “SB solution”.

After you spend some time in Logseq, you’ll find that there are many different ways to accomplish the same goal. I spent my first few weeks with Logseq establishing some standards in the way my notes were structured (page hierarchy, tags, task management, intake vs review workflows).

In the past I’ve recommended Logseq to friends and colleagues, but most find it too open ended to get started and the value is not immediately obvious.

Contrast that with something like capacities.io which comes with much more structure out of the box. If you’re unfamiliar, this overview is worth a watch.

I will always use open source tools, and I opted for SB over capacities or similar tools, but there’s something to be said for simplicity in getting started. Maybe that conflicts with the SB identity as “the hacker’s notebook”, but I think it’s about finding the right balance. I think SB has done a great job of that so far (kudos to your excellent docs and videos).


Enough of my rambling.

As to the specific functionality I’m looking for, here’s a more basic example.

I have 2 pages

  1. A journal page: [[ Journals/2024-03-05 ]]
  2. A topic page: [[ Project A/Feature X ]]

On the journal page, I create a bulleted list

- This lives on the journal page
- Now I want to write some stuff that should be immediately associated with another page
- So I create this item with a link ref to [[Project A/Feature X]]
  - Under the above parent "item", every nested "item" like this one should also be included in the reference back to the feature page
  - Any child item like this one
  - [ ] Or even a #funtask like this one, should now be associated to the project page

Now, when I visit the topic page, I want to be able to create a query that will render every task that is associated with this topic page, including the above #funtask that was created from a journal page. You can see how powerful this could become.

So I would look to write a task query, but currently none of the task attributes would allow me to accomplish this:

```query
task where ?
```

This is when I came across your “custom attribute extractors”. If I could write an extractor that will look at every task (or item), and “collect” all of the page references on this task or any of its parent items and compile the result into a new attribute, I believe this would allow me to write the query I’m looking for. It adds an attribute on each child item/task relating it to the link ref from any parent.

So in the example above, we would create some custom attribute parent_refs for all tasks, and now the #funtask will include the new attribute that contains the link ref to [[Project A/Feature X]].

It seems the problem with the extractor is that it’s not immediately obvious to me the best way to “jump from an item to its parent” as part of the link ref collection process, but I have not dug into the code base yet. Any idea if this is possible in the current extractor pattern?

1 Like

Yes I understand the request. This is not possible to implement with an attribute extractor now since you don’t have access to parents (or the rest of the document) there. I’d have to think how to support this.

1 Like

Understood. Thanks again for the reply.

I’ll try to find some time this weekend to get a better understanding of the code base.

1 Like

Being able to include nested list items in queries would be a game-changer!

4 Likes

I am also a Logseq user tempted by the programmability of SB and love the selfhost, PWA design of SB.

I can really subscribe to the three points with a big emphasis on 1. and 2.
Yes so the inheritance of the reference and editing of referenced text from other files without the contextswitch are both major strongpoint of LogSeq

@chipduvet

I’m self-hosting SilverBullet at home and was able to set up secure remote access.

If you are OK with Cloudflare’s ecosystem, consider connecting your SilverBullet Docker Container to a Cloudflare Tunnel (you just need to create a cloudflared Container in Docker.) That provides a secure VPN tunnel from the Internet to SilverBullet without having to open any ports on your router. But wait! That exposes your instance to the public. OK, so let’s secure it further. Add a Coundflare Application in front of the Tunnel to provide another layer of security by adding an authentication screen that a user must pass to get to SilverBullet. I like this methodology because a user never touches your server unless they provide proper credentials. Authentication methods can be as simple as an OTP sent to an email or more complex authentication services like Google or GitHub. (These require some setup but they are seamless to the user.)

Offline mode absolutely has its uses (I can think of several cases where this will be very useful) but I love having any time, anywhere remote access. I use this method for other services I self-host as well such as Kasm Workspaces, Bookstack, and many others.

@chipduvet

One other thing: You casually mentioned this query:

tasks where name =~ /swarna/

Dang! This is a game-changer for me in that this concept just simplified several queries. I’ve been using the “contains(str, substr)” command in and #if. Your solution is so much simpler!

1 Like