What's Changed
New Installer
This release replaces the terminal-based launcher introduced in 25.07 with a more standard installation process:
- Anki no longer shows a terminal on installation/update.
- Installation no longer requires network access.
- Updates can be installed using Tools>Check For Updates.
- A standard MSI installer is provided for Windows.
- A Windows ARM64 build is available.
- The macOS builds require macOS 13 or later.
- The Linux x86_64 build requires glibc 2.35+.
- The Linux aarch64 build requires glibc 2.39+.
- The minimum supported Python version is now 3.10 (The official builds still ship Python 3.13).
- Qt has been updated to 6.11
Note: The Tools>Upgrade/Downgrade option in 25.07+ cannot be used to upgrade to this version due to packaging changes.
By @abdnh @andrewsanchez @fernandolins @Luc-Mcgrady @iamllama in #4629
Documentation Improvements
- All user/developer documentation is now unified under a single website deployed from the main repo. The different docs repos will be archived and existing issues moved soon. By @andrewsanchez @Luc-Mcgrady @abdnh in #4882
- Python API docs can now be viewed in dev-docs.ankiweb.net. By @andrewsanchez in #4579
FSRS/Scheduling Changes
- Rework the efficiency ratio graph in FSRS Help Me Decide by @Luc-Mcgrady in #4452
- Require three left-clicks to unlock FSRS parameter editing by @Luc-Mcgrady in #4372
- Speed up FSRS memory state updates by batching calculations by @DanielPechersky in #4335
- Improve performance of
reviews_for_fsrsfunction by @L-M-Sherlock in #4339 - Fix/first and latest review dates should only consider entries with a rating. by @L-M-Sherlock in #4360
- Fix/Ensure fuzz doesn't go backward during rescheduling by @user1823 in #4364
- Fix/Per deck retention not used when card is moved to filtered deck by @Luc-Mcgrady in #4413
- Restore retrievability SQL fix that was accidentally reverted by @Luc-Mcgrady in #4424
- Fix/rounded corners on FSRS Simulator modal by @Luc-Mcgrady in #4535
- Fix FSRS short-term schedule being ignored when using default parameters by @L-M-Sherlock in #4412
- Use quantiles for FSRS retrievability stat ranges by @Luc-Mcgrady in #4425
- Make descending retrievability a pure R sort by @user1823 in #4400
- Don't reschedule suspended cards by @L-M-Sherlock in #4453
- Apply deck-specific load balancer settings to filtered deck study by @MoamenAbdelsattar in #4574
- Prioritize previously-attempted cards in the intraday learning queue by @user1823 in #4393
- Improve sibling dispersal in the load balancer, including across presets by @jakeprobst in #4640
- Fix desired retention not refreshing when switching deck option presets by @barisayyildiz in #4610
- Improve FSRS invalid parameters error message with FAQ link by @AmandaSternberg-creator in #4342
- Clarify ambiguous "this value" wording in desired retention tooltip by @Expertium in #4647
- Expose
setParameterUnlockClickTimeoutMsfor FSRS parameter unlock timeout by @Luc-Mcgrady in #4810 - Export last_interval to Python by @user1823 in #4365
- Expose card decay and desired retention to the custom scheduler by @user1823 in #4880
- Remove broken retention rate help link in stats by @Hannanilsenn in #4329
Other Notable Changes
- Show saved custom colours in the image-occlusion fill tool colour picker on mobile by @iamllama in #4348
- Add support for
tag:nc:...(case-insensitive) tag searches by @iamllama in #4344 - Treat newlines as term breaks in search queries by @eliasjlara in #4336
- Add syntax for multi-card cloze deletions by @tfpgh in #4333
- Remember image-occlusion translucency toggle between sessions by @dspilleb in #4366
- Fix "Restore to Default" picking the wrong template for basic notetype variants by @arold0 in #4382
- Let the "Limit to" spin box grow with its content in the filtered deck dialog by @jcznk in #4398
- Fix unescaped HTML in correct type-in answers by @Eltaurus-Lt in #4407
- Always show text boxes on image-occlusion cards during review by @jariji in #4387
- Fix FindDuplicates dialog size exceeding screen bounds by @Nechaiter in #4426
- Fall back to Apple Samantha for TTS on macOS when no requested voice matches by @leedoughty in #4420
- Allow variable field counts per row when CSV import uses a notetype column by @iamllama in #4421
- Improve handling of media files differing only in letter case by @iamllama in #4355 #4851 #4860 #4861 #4852
- Keep non-breaking spaces outside cloze deletions when wrapping text by @leedoughty in #4446
- Start decoding images immediately by @SelfishPig in #4471
- Revert ForceDarkMode change that interfered with Anki's native dark theme by @GithubAnon0000 in #4483
- Apply the nightMode class to the editor in dark mode so custom HTML styles correctly by @leedoughty in #4473
- Auto-select the relevant note type in the Manage Note Types dialog after add/rename by @Arthur-Milchior in #4479
- Fix field rename by matching on the old name rather than field position by @Arthur-Milchior in #4488
- Allow horizontal scrolling on the deck options screen so AnkiDroid handles large font sizes by @defkorean in #4501
- Fix
{{#Tags}}conditional not triggering card generation by @Yuukidiv in #4533 - Silence console spam from image decoding errors during preload by @SelfishPig in #4534
- Add note type and GUID column headers to deleted.txt for easier reimport by @hnvy in #4454
- Apply Ctrl/Cmd+W window-closing shortcut globally to all dialogs by @beyondcompute in #4475
- Fix overlapping date ranges in graphs when "all history" is selected by @JMannervik in #4430
- Add a preference to disable the startup add-on update check by @SecretX33 in #4478
- Add
dir="auto"to cards so text direction no longer depends on the UI language by @MoamenAbdelsattar in #4428 - Accept images with capitalized extensions in the Browse "Attach" dialog by @miggazElquez in #4474
- Re-enable WindowsRT TTS player on Windows 11 by @abdnh in #4512
- Fix HTML editor collapsing after toggling sticky fields and adding a note by @Yuukidiv in #4566
- Fix image occlusion editor layout for right-to-left languages by @MoamenAbdelsattar in #4594
- Speed up tag autocomplete by using the Rust backend's complete_tag() by @user1823 in #4626
- Detect cloze fields nested inside conditionals during card generation by @maskady in #4651
- Prompt to save unsaved changes when closing or switching debug console scripts by @Arthur-Milchior in #4625
- Roll back the sidebar tag name when the backend rejects a rename by @chrislongros in #4718
- Improve word wrapping on the Deck Options screen for narrow viewports by @defkorean in #4558
- Update to mpv 0.41.0 by @abdnh in #4913
- Bundle Fcitx plugin on Linux by @abdnh in #4886
- Install required Linux system dependencies in install.sh by @abdnh in #4895
- Render sync server messages as rich text by @timarnoldev in #4560
Other Improvements
- Fix progress bar overflow crash when one-way uploads exceed 2 GB by @matbe766 in #4354
- Fix fatal error from rapidly double-clicking the Add button by @arold0 in #4377
- Use the native
crypto.randomUUID()instead of a custom UUID implementation by @leedoughty in #4384 - Credit Arabic translation contributor in the About window by @hnvy in #4720
- Tighten
Collection.add_notestype annotation so single-pass iterables aren't accepted by @jfly in #4758 - Set a friendly process job name for mpv on Windows by @abdnh in #4438
- Add Rust unit tests for the card-generation logic by @Yuukidiv in #4551
- Add punctuation, convert raw URLs to markdown links in READMEs by @oliolioli in #4570
- Reorder and comment .ftl files in UI order to help translators by @RolfMaster in #4514
- Show tooltips for truncated sidebar items in the Browse window by @nav1s in #4385
- Stop showing an error toast when saving an image-occlusion note twice on mobile by @iamllama in #4458
- Render
<br>as a line break in card template error messages instead of literal text by @leedoughty in #4451 - Use a true minus sign instead of a hyphen in the deck browser by @GithubAnon0000 in #4437
- Fix sync login dialog ignoring a freshly-set custom sync server URL by @ranjitodedra in #4396
- Add plural forms to unit labels next to spin boxes in the Custom Study dialog by @RolfMaster in #4520
- Don't expose collection.media.db2 over the API by @dae in #4653
- Update media sync progress dialog correctly after an error occurs in #4486
- Disable the Custom Study OK button when the selected deck is empty by @tunamayo04 in #4463
- Warn the user when renaming a profile would exceed the OS path length limit in #4552
- Fix regex error by @chiragjagga in #4837
- Preserve browser focus after note export by @Tfc538 in #4845
- Avoid loading unused cacert.pem by @abdnh in #4858
- Strip HTML from note type names in Empty Cards dialog by @abdnh in #4902
- Parameterize inputs of prop:cd* queries by @abdnh in #4905
- Validate add-on zip entries by @abdnh in #4901
- Repaint UI after answer reveal to reduce glitches on cards with images by @abdnh in #4970
Developer Improvements
- The release build process is now fully automated using GitHub Actions. By @andrewsanchez @abdnh @fernandolins in #4632
- Migrate CI from BuildKite to GitHub Actions. By @andrewsanchez @abdnh @fernandolins in #4593
- Update to Rust 1.92 by @abdnh in #4461
- Add Dependabot config with monthly grouped updates by @fernandolins in #4726
- Update PyCharm docs by @abdnh in #4389
- Update VS Code config by @abdnh in #4397
- Treat proto/i18n's implicit outputs as inputs by @iamllama in #4439
- Respect .python-version when generating pyenv by @iamllama in #4436
- Add more required packages to Linux build guide by @user1823 in #4432
- Only run cargo-deny if there are dependency changes by @abdnh in #4644
- Remove old GPG public key by @dae in #4707
- Raise dependabot open-pull-requests-limit to 3 by @fernandolins in #4746
- Add release-age controls for uv and Yarn dependencies by @fernandolins in #4761
- docs: add contributing guidelines for add-ons, linked issues, and AI-assisted PRs by @fernandolins in #4782
- Add pre-commit for automated pre-push checks by @fernandolins in #4660
- Add a standardized pull request template by @fernandolins in #4655
- Exclude BackendFrontendService from write_python_interface by @Luc-Mcgrady in #4410
- Add regression test for #1909 (media check long filenames) by @bds124 in #4476
- Update docker build command for syncserver by @CYPHER0041 in #4562
- Exclude more folders from build actions by @abdnh in #4561
- Add Windows quick start guide for new contributors by @DaniSilvaCodes in #4466
- Update Windows developer docs by @user1823 in #4662
- Ignore Fluent message errors in TypeScript by @abdnh in #4494
- Drop QDialog argument from grade_now() to make it add-on friendly by @abdnh in #4459
- Wrap previewer type field syntax replacement in separate method by @DaedalusIndigo in #4563
- Document that
add_deckrequires refetching the deck to see its new ID by @jfly in #4760 - Update security.md by @andrewsanchez in #4790
- Add missing PyPI metadata to anki package by @fernandolins in #4817
- Fix beta/rc suffix handling in int_version() by @abdnh in #4828
- Prevent Windows elevation errors when running ninja_gen's update binaries by @abdnh in #4848
- Fix
atomic_renameto work with single-component relative paths by @jfly in #4773 - Add Python test coverage by @fernandolins in #4841
- Add Rust test coverage by @fernandolins in #4842
- Add TypeScript test coverage by @fernandolins in #4843
- Add test coverage docs by @fernandolins in #4844
- Add tests for build_installer.py by @abdnh in #4868
- Add Playwright end-to-end test infrastructure by @fernandolins in #4864
- Cache coverage baseline from main for regression checks by @fernandolins in #4875
- Replace print() logging in pylib with Python logging by @davidsauerwein in #4666
- Avoid broad warnings filter by @abdnh in #4900
- Enforce linked issue requirement on PRs by @fernandolins in #4910
- Fail PR if line coverage regresses by @fernandolins in #4876
- Import some modules lazily by @abdnh in #4831
- Add hash script for GitHub Actions by @Luc-Mcgrady in #4991
- Add unit tests for CSV export and import-export service layer by @fernandolins in #4976
- Add tests for attribute and tag stripping in HTML filter by @leedoughty in #4965
- Add unit tests for learning and relearning state transitions by @fernandolins in #4963
- Replace deprecated global map-get/map-merge with sass:map namespace by @fernandolins in #4955
- Remove unused Bootstrap imports from _button-mixins.scss by @fernandolins in #4953
- Integrate Complexipy for Python complexity analysis by @abdnh in #4942 and #4987
- Consolidated security dependency updates (Dependabot batch) by @fernandolins in #4934
- Add just recipes for run, web-watch, rebuild-web, and clean, and add AGENTS.md by @fernandolins in #4943
- Expand contributing guide with PR process and test requirements by @fernandolins in #4946
- Prevent duplicate 'missing linked issue' comments on PR edits by @fernandolins in #4937
- Use commit SHAs for GitHub Actions dependencies by @Luc-Mcgrady in #4916
- Use PowerShell to run just commands on Windows by @abdnh in #4921
- Exclude github-actions[bot] from contributor check by @abdnh in #4923
New Contributors
- @Hannanilsenn made their first contribution in #4329
- @eliasjlara made their first contribution in #4336
- @tfpgh made their first contribution in #4333
- @dspilleb made their first contribution in #4366
- @matbe766 made their first contribution in #4354
- @AmandaSternberg-creator made their first contribution in #4342
- @arold0 made their first contribution in #4377
- @nav1s made their first contribution in #4385
- @ranjitodedra made their first contribution in #4396
- @Eltaurus-Lt made their first contribution in #4407
- @jariji made their first contribution in #4387
- @Nechaiter made their first contribution in #4426
- @SelfishPig made their first contribution in #4471
- @bds124 made their first contribution in #4476
- @tunamayo04 made their first contribution in #4463
- @defkorean made their first contribution in #4501
- @RolfMaster made their first contribution in #4514
- @Yuukidiv made their first contribution in #4533
- @JMannervik made their first contribution in #4430
- @SecretX33 made their first contribution in #4478
- @DanielPechersky made their first contribution in #4335
- @MoamenAbdelsattar made their first contribution in #4428
- @DaedalusIndigo made their first contribution in #4563
- @miggazElquez made their first contribution in #4474
- @oliolioli made their first contribution in #4570
- @DaniSilvaCodes made their first contribution in #4466
- @chrislongros made their first contribution in #4668
- @CYPHER0041 made their first contribution in #4562
- @maskady made their first contribution in #4651
- @jfly made their first contribution in #4758
- @barisayyildiz made their first contribution in #4610
- @chiragjagga made their first contribution in #4837
- @Tfc538 made their first contribution in #4845
- @davidsauerwein made their first contribution in #4666
- @timarnoldev made their first contribution in #4560
Full Changelog: 25.09.4...26.05