0.28.0 (20k stars ⭐)
Welcome to the 0.28.0 release of Karakeep! We've have hit 20k stars on Github 🎉 (well 21k because I was too late with the release)! Thanks a lot for your support throughout this journey! This release brings a refreshed import pipeline, uploading custom attachments, revamped tags page, inline checklists, and a bunch of quality-of-life touches across the web app, extension and mobile app. Huge thanks to @BOTkirial, @qixing-jk, @@maya-doshi, @BenjaminMichaelis, @cloudchristoph, @claytono, as usual @xuatz and everyone who shipped code, triaged bugs, or shared feedback for this release.
If you enjoy using Karakeep, consider supporting the project here ☕️ or via GitHub here.
And in case you missed it, we now have a ☁️ managed offering ☁️ for those who don't want to self-host. We're still in private beta (you can signup for access here) and gradually letting more and more users in.
New Features 🚀
- Revamped import experience with progress tracking (#2001)
- Revamped Tags page that adds search and pagination to better serve users with thousands of tags (#1987)
- You can now upload custom attachments to bookmarks (#2100)
- When deleting a list, you can now optionally delete all its children (#1989)
- Server overview highlights service dependency health.
- Inline checklist toggling for text bookmarks (#1933) – @BOTkirial
- With every release, you'll be prompted to view what's new in that release from inside the app.
- You can now pass custom headers from the mobile app to the server (#2103)
- Extension improvements:
- Tab bookmark badge indicator by @qixing-jk shows when a page is already bookmarked (#1745)
- You can now write notes directly after saving a bookmark in the extension (#2104)
UX Improvements ✨
- Grid view controls expose title/tag toggles and image fit options (#1960)
- Bookmark cards can surface saved notes across web and mobile (#2083) – @xuatz
- Manage Lists modal is searchable for faster sorting (#2029)
- The tags page now has a "Create Tag" button (#1942)
- You can now regenerate the API key without having to recreate it.
- New
title:seach qualifier for searching bookmarks by title (#1940)
Fixes 🔧
- ⚠️ (Potentially breaking change) ⚠️ Stricter URL valdaition to protect against SSRF attacks (#2082)
- Webhook requests now go through the proxy if there's one configured
- All server-initiated requests (including webhooks) to internal IP addresses are now blocked by default unless explicitly allowed via
CRAWLER_ALLOWED_INTERNAL_HOSTNAMES. If your webhooks are hitting internal services, you'll have to allowlist them viaCRAWLER_ALLOWED_INTERNAL_HOSTNAMES. - Monolith now honors the configured crawler proxy.
- Metascraper logo extraction now respects the crawler proxy.
- Crawler memory footprint shrinks with targeted optimizations (#1748)
- Allow karakeep to use newer openai models that was previously failing because of deprecated max_tokens (#2000) - @BenjaminMichaelis
- You'll need to set
INFERENCE_USE_MAX_COMPLETION_TOKENS=truein your.envfile to use the new models. This is eventually going to become the default.
- You'll need to set
- Admin maintenance jobs respect abort signals to stop gracefully
- Search input no longer crashes on percent signs and also works correctly with IME composition
- Fixed a crash when sharing a list publicly that didn't have any bookmarks (#1990)
- Screenshots are now stored as jpegs instead of pngs to reduce file size
- Fixed a bug that was preventing tag merging (#1938)
- RSS imports can apply feed categories as tags (#2031)
For Developers 🛠️
- Create bookmark API returns 200 instead of 201 when a bookmark already exists
- CLI Improvements:
- New commands to migrate data from one server to another
- New command to dump a full account archive
- A new wipe command to selectively clean up data from the account
Community Projects 💡
Karakeeper
3rd Party iOS/Safari Client - by @simplytoast1
Karakeeper now is providing an alternative iOS native mobile/desktop client for Karakeep beyond its existing functionality of providing a safari extension.
Karakeep Sync
A syncing tool for Karakeep - by @sidoshi
A rust-based syncing tool that syncs: Hacker News upvotes, Reddit saved posts, Github stars and Pinboard bookmarks automatically to Karakeep!
Screenshots 📸
Inline Checklists
Import Sessions
Service Health Indicators
Upgrading 📦
To upgrade:
- If you're using
KARAKEEP_VERSION=release, rundocker compose pull && docker compose up -d. - If you're pinning it to a specific version, bump the version and then run
docker compose pull && docker compose up -d.
All Commits
- fix: standardize US English translations to professional tone - @MohamedBassem in 4f025f5
- i18n: Sync weblate translations - @weblate in 5387c98
- tests: fix crawling and search e2e tests (#2105) - @MohamedBassem in c4bee9f
- feat(extension): Allow writing notes directly in the extension (#2104) - @MohamedBassem in 098e56a
- fix(mobile): fix default address not correctly stored in settings - @MohamedBassem in a220319
- feat(mobile): add custom headers configuration in sign-in screen (#2103) - @MohamedBassem in ec621bf
- tests: Fix failing test - @MohamedBassem in 27ed0a1
- feat: Add what's new modal in the sidebar (#2099) - @MohamedBassem in 474f642
- feat: Add support for user uploaded files (#2100) - @MohamedBassem in 31960fc
- refactor: consolidate multiple karakeep plugins into one package (#2101) - @MohamedBassem in 99413db
- fix: metascraper logo to go through proxy if one configured. fixes #1863 - @MohamedBassem in 737b031
- feat(extension): add tab bookmark badge indicator (#1745) - @qixing-jk in f0b0959
- fix: restore image size in grid layout - @MohamedBassem in 2056582
- deps: Upgrade react-query to 5.90 - @MohamedBassem in 560900b
- feat: Support inline toggling for todos. fixes #1931 (#1933) - @BOTkirial in 393bbd9
- fix: fix monolith to respect crawler proxy - @MohamedBassem in 085c832
- feat(rss): Add import tags from RSS feed categories (#2031) - @MohamedBassem in 5358682
- fix: fix crash in search input when query contains a percent. fixes #1941 - @MohamedBassem in 633686b
- feat: Add view options to show tag/title and control image fit. Fixes #1960 - @MohamedBassem in 34d2b48
- refactor: improve the userLocalSetting server functions - @MohamedBassem in bb00c99
- feat: Make search job timeout configurable - @MohamedBassem in 965c603
- feat: display notes on bookmark card (#2083) - @xuatz in 33f4077
- fix: Stricter SSRF validation (#2082) - @MohamedBassem in b63a49f
- fix: correctly handle composition in search input. fixes #2048 - @MohamedBassem in c6ebceb
- fix: browser service connection check using dns instead. Fixes #2080 - @MohamedBassem in c9c73d4
- fix: More memory optimizations for crawler worker. #1748 - @MohamedBassem in 40d548b
- fix: fix screenshot filepath in crawler - @MohamedBassem in 0704b8b
- docs: Add Azure configuration details for OpenAI-compatible API (#2072) - @cloudchristoph in bd9c933
- fix: Respect abort signal in admin maintenance jobs - @MohamedBassem in 8a330dc
- deps: Upgrade metascraper plugins - @MohamedBassem in e43c7e0
- deps: Upgrade metascraper-readability 5.49.6 - @MohamedBassem in 6d234de
- feat: Allow configuring inline asset size threshold - @MohamedBassem in cf3ffff
- feat: Add admin maintenance job to migrate large inline HTML (#2071) - @MohamedBassem in 2b769cb
- fix(inferance): skip token slicing when content is already witin max length - @MohamedBassem in 1713600
- refactor: generalize tidy assets queue into admin maintenance (#2059) - @MohamedBassem in 6ea5dd1
- fix: update OpenAI API to use max_completion_tokens instead of max_tokens (#2000) - @BenjaminMichaelis in 046c29d
- fix(restate): Fix priority for restate queue - @MohamedBassem in 8c0aae3
- fix(restate): Ensure that the semaphore and idProvider services are ingress private - @MohamedBassem in cdf8121
- feat: Add source field to track bookmark creation sources (#2037) - @MohamedBassem in 2defc24
- feat: support passing multiple proxy values (#2039) - @MohamedBassem in c14b693
- deps: Upgrade oxlint to 1.22 - @MohamedBassem in 88a7ffe
- feat: Add service dependency checks in the server overview page - @MohamedBassem in fda1c85
- fix(web): Add w-full to tags editor to prevent unusable narrow width (#2035) - @MohamedBassem in 7ee9416
- fix(api): Return 200 when bookmark already exists instead of 200 - @MohamedBassem in f2dec26
- tests: Add a test for the GET /bookmarks/bookmarkId/lists api - @MohamedBassem in d578038
- fix(api): Document the API for getting lists of a bookmark. fixes #2030 - @MohamedBassem in 7f138b9
- feat: make list dropdown searchable in Manage Lists modal (#2029) - @MohamedBassem in 87053d2
- fix: fix dev script shebang for better compatibility (#2019) - @maya-doshi in dcddda5
- fix: Correct grammatical errors in prompts (#2020) - @atsggx in f1e8cea
- docs: Add karakeep-sync to community projects (#1994) - @sidoshi in 36ffbdf
- fix: round feed refresh hour for idempotency (#2013) - @MohamedBassem in bae8386
- fix: fix show no bookmark page when there isn't search results - @MohamedBassem in 57d731b
- fix: Disable idempotency keys for search - @MohamedBassem in b6867be
- feat: Restate-based queue plugin (#2011) - @MohamedBassem in 74a1f7b
- feat: Revamp import experience (#2001) - @MohamedBassem in 4a580d7
- docs: Add doc updates for prometheus metrics (#1957) - @claytono in 5e331a7
- fix: fix public list sharing for empty lists (#1990) - @MohamedBassem in 7df6d94
- feat: recursive list delete (#1989) - @MohamedBassem in 7d0b414
- feat: use jpegs for screenshots instead of pngs - @MohamedBassem in ed1f24f
- feat: Stop downloading video/audio in playwright - @MohamedBassem in 37845f9
- fix: Abort dangling processing when crawler is aborted (#1988) - @MohamedBassem in 9eecda1
- fix: Cleanup temp assets on monolith timeout - @MohamedBassem in 8dd84ef
- chore: Silence lint on and tags when it's intentional - @MohamedBassem in cdbedf6
- fix: dont re-enqueue indexing for a bookmark already pending indexing - @MohamedBassem in e395ac2
- feat: Add tag search and pagination (#1987) - @MohamedBassem in 62f7d90
- fix: optimize memory usage of tag listing - @MohamedBassem in 9fe09bf
- deps: Upgrade oxlint to 1.16 - @MohamedBassem in bbc5e6c
- fix: fix bundling liteque in the workers - @MohamedBassem in 851d3e2
- refactor: Move callsites to liteque to be behind a plugin - @MohamedBassem in 8d32055
- fix(dev): worker not started properly in helper start script (#1946) - @xuatz in 6ba61b4
- feat: Regen api keys - @MohamedBassem in 7671f4f
- release(cli): Bump CLI version to 0.27.1 - @MohamedBassem in 69ef2ff
- feat(cli): Give more targetting options for dump/migrate/wipe - @MohamedBassem in 6501f69
- release(cli): Bump CLI version to 0.27.0 - @MohamedBassem in 0700aab
- feat(cli): Implement a full account dump archive - @MohamedBassem in b9a8ca2
- feat(cli): Implement a wipe command in the CLI - @MohamedBassem in bc0e746
- feat: Add scripts to migrate all content from one server to the other - @MohamedBassem in 783f72c
- fix(web): Handle user deletion more gracefully - @MohamedBassem in 92e357f
- feat: A better looking catch all error boundary - @MohamedBassem in d53b282
- fix(web): fix error when attempting to merge tags. fixes #1938 - @MohamedBassem in d173b10
- feat: Add Create Tag button to tags page (#1942) - @MohamedBassem in 820b7e6
- chore: fix claude code action - @MohamedBassem in c2dcb9d
- refactor: strongly type the search plugin interface - @MohamedBassem in bf5bf99
- feat(search): add title search qualifier (#1940) - @MohamedBassem in a92ada7
- feat(extension): add current tab title while saving from extension (#1930) - @abel in b594ff0