what is lifelab PKM edition
What is LifeLab: PKM edition
LifeLab remixes a lot of existing note taking concepts. There are a lot of such systems on the market, each with different UX assumptions and underlying technologies. In this page I will highlight the capabilities of LifeLab in terms of Personal Knowledge Management.
Tagging, backlinking, transclusion included
We have tags as separate metadata for each block. Tags can be nested/like/this which creates 3 nested pages. A page knows its child pages and links them. If you open a page, it aggregates all linked blocks! A block can be tagged (and thus linked) to multiple pages, but it has one owner page based on where it was created, usually the journal note. We can transclude individual blocks using a bit of code by leveraging the notebook api. It is not any specific query syntax you need to learn, it is just Python (or Rhai) with autocomplete within the app.
Everything is a block (but a different kind of block)
In LifeLab, we have individual units (similar to zettelkasten cards, roughly paragraph sized) called blocks. This is different from block-based note taking apps, where each row is a block. A block can have an entire blog post (for example, this exported post is stored in 1 block), executable code, json data object, table object or image. We can link and aggregate these blocks into pages using tags.
Ingest anything (but DIY)
One issue with note taking apps is the ingestion. Many PKMs have an inbox folder and put the onus on the user to categorize and organize it afterwards. In LifeLab, you have fully configurable ingestion endpoint with hooks. It works like this:
- Content is sent to the /api/ingest endpoint
- the backend loads code blocks with hooks tag, checks if they work on the content (we can filter based on source, content type like images, audio or text) and runs it.
- The codeblocks contain all intelligence. They can create pages, add blocks, or do nothing
The idea is, you define the rules and outcomes what should happen when you ingest data.This is usually defined by the developer, but here it is solely a user responsibility. For example in the telegram bot, I have some examples I use today:
- parse message for TODO, create a task block with the message as content
- if it is image, just add it to todays journal block
- if it is text, we can run NER and pattern matching (again, the code block can query the database for existing pages!) to suggest tags. Suggested tags are shown with a confirmation prompt
- We can run extraction LLM to convert text into structured format, we store existing schemas as blocks!
- if it's audio, we can run ASR!
flowchart TB
subgraph Sources["Data Sources"]
User["Direct Web Input"]
TG["Telegram Message"]
AI["Claude via MCP"]
Import["Data Import<br/>(Obsidian, Notion)"]
end
subgraph Ingest["Ingestion Layer"]
API["/api/ingest"]
Meta["Metadata Enrichment<br/>source, timestamp, user"]
end
subgraph Processing["Processing"]
Page["Determine Target Page<br/>(journal/YYYY-MM-DD)"]
Hooks["Trigger Hooks<br/>event: ingest"]
end
subgraph Storage["Storage"]
Block["Create Block"]
Links["Generate Links"]
DB[("PostgreSQL")]
end
User --> API
TG --> API
AI --> API
Import --> API
API --> Meta
Meta --> Page
Page --> Hooks
Hooks --> Block
Block --> Links
Links --> DB
Supertags present (but DIY)
A supertag is a sort of template associated with a tag, that is automatically applied when you use the tag. For example, this ensures each block with tag person automatically gets address and birthday metadata. It is very well executed by Tana and a killer feature. In LifeLab, we have hooks. Hooks are events (such as creating a block, creating a page, tagging a block, pressing a button) that execute code. So you can just add the metadata or templates by yourself! The issue is Tana is very good at maintaining the supertags; If you update it in one place, it is applied to all tagged blocks. This is not the case in lifelab.
Publishing included (but DIY)
Each individual page can be published tapping a button. They are exported into static html files. There are two ways to share your content:
- One is to get a link from within your self hosted backend, getting a <your_url>/public/your_page endpoint which does not need authentication (the actual backend does need authentication)
- One is static export of all published pages into a separate folder. You can just point caddy to it to host it. This blog is hosted using that method. During export, LifeLab goes through all blocks and checks if they are tagged by a published page. It runs all code cells set for publication and stores the output in the html file.
Dashboards included (but DIY)
You have full power of Python and a well-defined API that query the database. LifeLab supports html and png output. Go wild. But do it yourself. Check what is lifelab data scientist edition for a dashbboard
Self hosted with database
LifeLab is not local-first, and it is not based on markdown files. It is meant to be hosted on the web behind authentication and https, which is admittedly an involved setup. It is powered by database for ideological reasons. My conviction is as strong as the conviction of markdown-file people.
NO MARKDOWN FILES
I don't believe markdown files are a good long term format for personal linked notes, because the weak schema is too flexible and the output becomes spaghetti after a year. I used Obsidian for 2 years and Silverbullet for another 2. Both are markdown format powered which is incredible to read using text editor, but actually terrible to parse, process and transform reliably. This is because we often impose our own structure which ends up looking like a graph or tree, but there is no one correct way to create this structure from raw text.
I thought I was fairly systematic but things like MOC pages introduce so much abstraction no other app can fully understand it, because it has to understand the user intent.
On the other hand, LifeLab has a strict page-block schema which allows instant html and markdown export. The database can create a view of the data that is tailored to the export and ties our inner understanding of the data and the expected output together. I believe filesystem is just a more user friendly, less performant database and we can bridge the gap to more performant databases by having a good enough interface.
YES MARKDOWN FORMAT
On the other hand, I love markdown format because the most I do is headers and bold text. I feel rich text formatting gets in the way of text processing using python (it has to be stripped away), so I strongly prefer to have the raw text clean with minimal bling. I love the format because it has enough things I need, like lists, headers and links. I just don't belive markdown is good for any sort of structure apart from self imposed disciplined meticulous organization. But shouldn't the software do that for you?
Journal view, quasi-zettelkasten
LifeLab is more focuses on chronological logging of information, so it has a daily page and a calendar view, blocks are meant to be added to the daily note and linked to pages via tags. Blocks are supposed to be fairly atomic to be remixed and linked in other blocks. The journal view makes it easy to generate weekly, monthly, and yearly summaries.