v0.28.0
karakeep-app/karakeepv0.28.0Nov 8, 2025by MohamedBassem
AI Summary
Celebrating 20k stars, this release features a revamped import pipeline with progress tracking, custom attachment uploads, and a redesigned tags page with search and pagination. It also implements stricter SSRF validation for security.
Key Highlights
- Revamped import experience with detailed progress tracking.
- Revamped Tags page featuring search and pagination.
- Ability to upload custom attachments to bookmarks.
- Inline checklist toggling for text bookmarks.
- Stricter URL validation to protect against SSRF attacks.
Breaking Changes
- Stricter URL validation blocks server-initiated requests to internal IP addresses by default, requiring configuration via `CRAWLER_ALLOWED_INTERNAL_HOSTNAMES`.
New Features
- Import pipeline with progress tracking and pause capability.
- Tags page with search and pagination.
- Custom attachment uploads.
- Inline checklist support.
- Website-aware previews for specific platforms (Twitter, Amazon, YouTube, TikTok).
- Custom headers support in mobile app.
- Tab bookmark badge indicators.
- Regeneration of API keys.
- CLI commands for migrating data, dumping archives, and wiping data.
- Source tracking for bookmark creation.
Full Release Notes
# 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 ☕️](https://buymeacoffee.com/mbassem) or via GitHub [here](https://github.com/sponsors/MohamedBassem). <a href="https://www.buymeacoffee.com/mbassem" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" width="auto" height="50" ></a> 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](https://tally.so/r/wo8zzx)) 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 via `CRAWLER_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=true` in your `.env` file to use the new models. This is eventually going to become the default. - 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](https://apps.apple.com/us/app/karakeeper-for-karakeep/id6746722790) 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](https://github.com/sidoshi/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 <img width="1230" height="806" alt="Screenshot 2025-11-08 at 8 55 18@2x" src="https://github.com/user-attachments/assets/c092d903-eb6f-40c6-aee6-1ce6127f67e8" /> ## Import Sessions <img width="1814" height="762" alt="Screenshot 2025-11-08 at 8 58 21@2x" src="https://github.com/user-attachments/assets/dfcb856b-6a63-4d7a-ba4b-ce2ca83bc844" /> ## Service Health Indicators <img width="1874" height="540" alt="Screenshot 2025-11-08 at 8 56 00@2x" src="https://github.com/user-attachments/assets/7835f1ad-239d-477c-8e00-951e4a09f8c6" /> # Upgrading 📦 To upgrade: * If you're using `KARAKEEP_VERSION=release`, run `docker 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 4f025f5a * i18n: Sync weblate translations - @weblate in 5387c982 * tests: fix crawling and search e2e tests (#2105) - @MohamedBassem in c4bee9fe * feat(extension): Allow writing notes directly in the extension (#2104) - @MohamedBassem in 098e56a8 * fix(mobile): fix default address not correctly stored in settings - @MohamedBassem in a2203196 * feat(mobile): add custom headers configuration in sign-in screen (#2103) - @MohamedBassem in ec621bf5 * tests: Fix failing test - @MohamedBassem in 27ed0a19 * feat: Add what's new modal in the sidebar (#2099) - @MohamedBassem in 474f6429 * feat: Add support for user uploaded files (#2100) - @MohamedBassem in 31960fcd * refactor: consolidate multiple karakeep plugins into one package (#2101) - @MohamedBassem in 99413db0 * fix: metascraper logo to go through proxy if one configured. fixes #1863 - @MohamedBassem in 737b0317 * feat(extension): add tab bookmark badge indicator (#1745) - @qixing-jk in f0b0959e * fix: restore image size in grid layout - @MohamedBassem in 2056582c * deps: Upgrade react-query to 5.90 - @MohamedBassem in 560900bb * feat: Support inline toggling for todos. fixes #1931 (#1933) - @BOTkirial in 393bbd9a * fix: fix monolith to respect crawler proxy - @MohamedBassem in 085c832c * feat(rss): Add import tags from RSS feed categories (#2031) - @MohamedBassem in 5358682a * fix: fix crash in search input when query contains a percent. fixes #1941 - @MohamedBassem in 633686b5 * feat: Add view options to show tag/title and control image fit. Fixes #1960 - @MohamedBassem in 34d2b485 * refactor: improve the userLocalSetting server functions - @MohamedBassem in bb00c996 * feat: Make search job timeout configurable - @MohamedBassem in 965c603d * feat: display notes on bookmark card (#2083) - @xuatz in 33f40779 * fix: Stricter SSRF validation (#2082) - @MohamedBassem in b63a49fc * fix: correctly handle composition in search input. fixes #2048 - @MohamedBassem in c6ebceb9 * fix: browser service connection check using dns instead. Fixes #2080 - @MohamedBassem in c9c73d41 * fix: More memory optimizations for crawler worker. #1748 - @MohamedBassem in 40d548bd * fix: fix screenshot filepath in crawler - @MohamedBassem in 0704b8bb * docs: Add Azure configuration details for OpenAI-compatible API (#2072) - @cloudchristoph in bd9c933b * fix: Respect abort signal in admin maintenance jobs - @MohamedBassem in 8a330dc2 * deps: Upgrade metascraper plugins - @MohamedBassem in e43c7e0f * deps: Upgrade metascraper-readability 5.49.6 - @MohamedBassem in 6d234de8 * feat: Allow configuring inline asset size threshold - @MohamedBassem in cf3ffff0 * feat: Add admin maintenance job to migrate large inline HTML (#2071) - @MohamedBassem in 2b769cba * fix(inferance): skip token slicing when content is already witin max length - @MohamedBassem in 17136006 * refactor: generalize tidy assets queue into admin maintenance (#2059) - @MohamedBassem in 6ea5dd19 * fix: update OpenAI API to use max_completion_tokens instead of max_tokens (#2000) - @BenjaminMichaelis in 046c29dc * fix(restate): Fix priority for restate queue - @MohamedBassem in 8c0aae33 * fix(restate): Ensure that the semaphore and idProvider services are ingress private - @MohamedBassem in cdf81213 * feat: Add source field to track bookmark creation sources (#2037) - @MohamedBassem in 2defc247 * feat: support passing multiple proxy values (#2039) - @MohamedBassem in c14b6934 * deps: Upgrade oxlint to 1.22 - @MohamedBassem in 88a7ffec * feat: Add service dependency checks in the server overview page - @MohamedBassem in fda1c851 * fix(web): Add w-full to tags editor to prevent unusable narrow width (#2035) - @MohamedBassem in 7ee9416e * fix(api): Return 200 when bookmark already exists instead of 200 - @MohamedBassem in f2dec26f * tests: Add a test for the GET /bookmarks/bookmarkId/lists api - @MohamedBassem in d5780388 * fix(api): Document the API for getting lists of a bookmark. fixes #2030 - @MohamedBassem in 7f138b99 * feat: make list dropdown searchable in Manage Lists modal (#2029) - @MohamedBassem in 87053d2e * fix: fix dev script shebang for better compatibility (#2019) - @maya-doshi in dcddda56 * fix: Correct grammatical errors in prompts (#2020) - @atsggx in f1e8cea2 * docs: Add karakeep-sync to community projects (#1994) - @sidoshi in 36ffbdf8 * fix: round feed refresh hour for idempotency (#2013) - @MohamedBassem in bae8386d * fix: fix show no bookmark page when there isn't search results - @MohamedBassem in 57d731ba * fix: Disable idempotency keys for search - @MohamedBassem in b6867be4 * feat: Restate-based queue plugin (#2011) - @MohamedBassem in 74a1f7b6 * feat: Revamp import experience (#2001) - @MohamedBassem in 4a580d71 * docs: Add doc updates for prometheus metrics (#1957) - @claytono in 5e331a7d * fix: fix public list sharing for empty lists (#1990) - @MohamedBassem in 7df6d942 * feat: recursive list delete (#1989) - @MohamedBassem in 7d0b414f * feat: use jpegs for screenshots instead of pngs - @MohamedBassem in ed1f24f2 * feat: Stop downloading video/audio in playwright - @MohamedBassem in 37845f99 * fix: Abort dangling processing when crawler is aborted (#1988) - @MohamedBassem in 9eecda18 * fix: Cleanup temp assets on monolith timeout - @MohamedBassem in 8dd84ef5 * chore: Silence lint on <a> and <img> tags when it's intentional - @MohamedBassem in cdbedf6c * fix: dont re-enqueue indexing for a bookmark already pending indexing - @MohamedBassem in e395ac27 * feat: Add tag search and pagination (#1987) - @MohamedBassem in 62f7d900 * fix: optimize memory usage of tag listing - @MohamedBassem in 9fe09bfa * deps: Upgrade oxlint to 1.16 - @MohamedBassem in bbc5e6c2 * fix: fix bundling liteque in the workers - @MohamedBassem in 851d3e29 * refactor: Move callsites to liteque to be behind a plugin - @MohamedBassem in 8d320554 * fix(dev): worker not started properly in helper start script (#1946) - @xuatz in 6ba61b46 * feat: Regen api keys - @MohamedBassem in 7671f4ff * release(cli): Bump CLI version to 0.27.1 - @MohamedBassem in 69ef2ffe * feat(cli): Give more targetting options for dump/migrate/wipe - @MohamedBassem in 6501f69a * release(cli): Bump CLI version to 0.27.0 - @MohamedBassem in 0700aab8 * feat(cli): Implement a full account dump archive - @MohamedBassem in b9a8ca29 * feat(cli): Implement a wipe command in the CLI - @MohamedBassem in bc0e7461 * feat: Add scripts to migrate all content from one server to the other - @MohamedBassem in 783f72cb * fix(web): Handle user deletion more gracefully - @MohamedBassem in 92e357f1 * feat: A better looking catch all error boundary - @MohamedBassem in d53b2826 * fix(web): fix error when attempting to merge tags. fixes #1938 - @MohamedBassem in d173b101 * feat: Add Create Tag button to tags page (#1942) - @MohamedBassem in 820b7e65 * chore: fix claude code action - @MohamedBassem in c2dcb9dc * refactor: strongly type the search plugin interface - @MohamedBassem in bf5bf996 * feat(search): add title search qualifier (#1940) - @MohamedBassem in a92ada77 * feat(extension): add current tab title while saving from extension (#1930) - @Abel in b594ff09