Markit is a self-hostable, block-based note-taking app created to provide an intuitive, functional environment enriched with useful tech-integrations. Focusing on speed, organization, and seamless workflow integration to make note-taking a positive, efficient change in daily workflow. Built using .NET and Angular.
Problem statement
Note taking experience can be overwhelming these days, most tools overcomplicate the core need: capturing and organizing thoughts. Between app fatigue, feature overload, and privacy concerns, there’s a clear gap for a focused, self-hostable tool that respects a workflow instead of demanding one.
The solution
Markit exists for those who just want a simple, intuitive and private space to think and organize.
đź“– The Notebook effect
The simple act of grabbing a notebook, assigning it a specific purpose, and filling its bounded pages with structure works incredibly well for capturing and connecting new ideas because it aligns perfectly with how our brains naturally process, organize, and value information.
Digital wikis like Notion or Obsidian encourage endless branching through hyperlinks, making it easy to lose focus. A structured notebook by contrast, provides a linear, flow of thought. For example, a kid studying math takes his notebook and starts his journey by naming a new page “Geometry”. He’s actually creating a mental framework. That’s why i chose to implement a block-based hierarchy on markit to allow users create a customized cognitive architecture that is inspired in a natural “notebook” workflow.
🗂️ Simple and familiar directory
Knowledge management isn’t just about storing information; it is about understanding it.
Organization is a key step to managing knowledge efficiently, from simple to the most complex cases. Workspaces in markit are built using a tree-based directory, allowing to nest notebooks and collections to any depth.
đź§© Simplicity without losing connection
Staying simple doesn’t mean staying isolated, these are some of the features that are implemented on markit without introducing noise:
- Markdown: Blocks are stored in markdown, keeping content portable and future-proof.
- Full-text search: Find anything across your workspace instantly, without relying on perfect organization.
- OAuth 2.0 sign-in: Log in with Google or GitHub.
- GitHub Gist integration: Paste a Gist URL to instantly embed and navigate code snippets with full semantic context, right inside blocks.
The stack
| Layer | Technology | Key Features |
|---|---|---|
| Frontend | Angular 20 | Standalone Components, Signals, PrimeNG UI, TipTap editor, CodeMirror |
| Backend | .NET 9 | Clean Architecture, CQRS, EF Core |
| Database | PostgreSQL | Relational Data Integrity, full-text search |
| DevOps | Docker & GitHub Actions | PostgreSQL container, composite action pipeline. |
Challenges and solutions
- Building a robust authentication system: implemented using ASP.NET Identity with JWT-based sessions delivered via HttpOnly cookies, token refresh, and OAuth 2.0 integrations with Google and GitHub.
- Modeling deeply nested workspaces efficiently: solved with a hierarchical structure and recursive CTEs for performant tree queries.
- Preventing data loss without server overload: handled with a debouncer, real-time autosave, and a retry strategy with exponential backoff.
- Searching across multiple fields with ranked results: built using PostgreSQL tsvector and tsquery for full-text search with relevance scoring.
- Loading large datasets smoothly: implemented cursor-based pagination and cache strategies to deliver a seamless and efficient browsing experience.
- Automating multi-environment deployments: built a GitHub Actions pipeline using a composite action that encapsulates all build and deploy steps, shipping to independent staging and production environments on a VPS on every push.
Screenshots