AnkiBase is a self-hosted web app for language learners. It runs your real Anki collection in the browser, plays Quizlet sets in every Quizlet mode, and uses AI to turn the words you're learning into short stories you can read with tap-to-translate. It runs on your own server, so your decks stay with you.
- Anki's own reviewer: card order, daily limits, learning steps and burying all come from Anki itself. Each card takes about one fast call, so studying stays quick on big collections.
- Every note type renders properly: your templates' HTML and CSS run in a sandboxed frame with night mode (and day mode on light themes), images, audio buttons, cloze, type-in answers, MathJax and card scripts.
- Keyboard first: Space reveals, 1–4 answer, Ctrl+Z undoes, R replays audio. The answer buttons show the next intervals.
- Two-way sync with AnkiWeb or your own sync server (Settings → Sync), a conflict picker,
.apkgimport, and deck management.
![]() |
![]() |
Import a set from its link and study it in Flashcards, Learn, Write, Test, Match, Blast and Blocks. Learn works like Quizlet's, with goals, rounds, multiple choice followed by written answers, and mastery tracking. Sessions save as you go, and the Study hub lists every unfinished one so you can pick it back up.
- Pick a deck or set. Smart pick favours words you're still learning: for Anki it uses card states, and for Quizlet it uses starred and often-missed terms. Then Claude, ChatGPT, Gemini or your own local model (Ollama, Open WebUI, LM Studio) writes a story at your CEFR level, with optional translations.
- In Reading, every word is already annotated with its dictionary form, part of speech, meaning in context and grammar notes, so lookups are instant. Highlight a sentence and ask the AI to explain it.
- Words from your cards are highlighted, along with their inflected forms.
Search works like a dictionary, with pronunciation, senses, gender, plural and etymology. Next to it is "In your cards": every Anki note and Quizlet term that contains the word, along with its state.
A calendar heatmap, reviews over time, future due, card counts, intervals, ease, an hourly breakdown, answer buttons, true retention and cards added. Each view can be scoped to everything, one Anki deck or one Quizlet set. Quizlet gets its own terms to work on table.
Nine built-in themes, custom accent and base colours with a live preview, and theme import/export. Admins can set the server-wide default. Sliders, toggles and panels move with springy, velocity-aware motion.
The Android and iPhone apps run Anki's own engine on the phone: decks, studying, search, editing, .apkg import, stats and Anki's Deck Options all work with no connection at all. They only need the internet to sync, with AnkiWeb or your own sync server, and to reach your AnkiBase server for stories, AI and Quizlet, which they can also do without. What you opened from the server stays readable offline, and progress saved offline is sent when you're back.
They're built to feel like apps rather than a web page: no zooming, the layout clears notches, the Dynamic Island and the gesture bar, the answer buttons sit under your thumb, and the system bars follow your theme (on iPhone, the home screen icon too). Android: download the .apk from the latest release. iPhone: add the source https://apps.macr0.dev/static/ios/source.json in SideStore or AltStore and install AnkiBase from there (new builds show up as updates), or open the .ipa from the latest release in either, or build it yourself on Linux or a Mac (see ios/).
The same app runs on computers: download the Windows installer, the macOS .dmg or the Linux .AppImage from the latest release (see desktop/). They aren't code-signed, so the first launch needs one extra click: More info → Run anyway on Windows, right-click → Open on macOS.
- Multi-user with profiles: a profile is an Anki collection with its own media, sync login, stories and Quizlet sets. Users get the profiles you give them, and permissions for importing, AI, AI keys, managing profiles and the default theme.
- One-line install with optional nginx and Let's Encrypt (or Docker Compose), a setup wizard, and one-click updates that check the new version first, back up, and roll back if it doesn't start.
- Your own sync server in one click (Settings → Sync): Anki's own sync server runs next to AnkiBase at
https://<your AnkiBase>/syncserver/, so Anki Desktop, AnkiMobile, AnkiDroid and the iPhone app sync there instead of AnkiWeb. - AI is optional: everything else works without it. API keys are stored encrypted and only shown to those allowed to manage them.
| Layer | Tech |
|---|---|
| Frontend | React 19, TypeScript, Vite, Tailwind CSS v4 |
| Backend | FastAPI + Uvicorn, SQLite |
| Anki engine | anki-cli: Anki's own engine as one small service, a collection per profile. No Anki Desktop, no container per profile |
AnkiBase doesn't reimplement Anki. All the Anki work goes through anki-cli, which I built alongside AnkiBase as its engine and released as its own project: Anki's official engine as a fast headless server, a drop-in for AnkiConnect (its test suite passes), that also serves Anki's own Statistics and Deck Options screens. It's useful on its own too, for scripts or anything that used AnkiConnect. More in the docs. | AI (optional) | Anthropic Claude, OpenAI, Google Gemini (bring your own key), or any OpenAI-compatible server such as Ollama |
You need a Debian-based server (Debian 12/13 or Ubuntu 22.04+) with root access.
curl -fsSL https://raw.githubusercontent.com/Macro002/AnkiBase/main/install.sh | sudo bashThe installer:
- Installs Node.js 20 and Python if they're missing
- Builds the frontend
- Picks a free port, starting at 8000
- Generates the secret and encryption keys
- Creates the
ankibasesystemd service (andankibase-ankifor the Anki engine) - Optionally sets up nginx with a Let's Encrypt certificate
Open the address it prints. The setup wizard walks you through your admin account, your first profile, syncing your cards (AnkiWeb, your own sync server, or one it runs for you) and an optional AI key.
One container with everything (the web app, Anki's engine and the optional sync server); your data stays in ./data:
mkdir ankibase && cd ankibase
curl -fsSLO https://raw.githubusercontent.com/Macro002/AnkiBase/main/docker-compose.yml
docker compose up -dOpen http://<your server>:8000 for the setup wizard. Put it behind your reverse proxy for HTTPS; it reads X-Forwarded-Proto. Update with docker compose pull && docker compose up -d (the in-app Update button shows this too). From a checkout, docker compose up -d --build builds the image yourself.
Click Update in the header when it lights up. AnkiBase follows tagged releases: it builds and checks the new version, backs up your code and data to /opt/ankibase/backups/, installs it, and puts the old version back if the new one doesn't start. To follow every commit instead, set UPDATE_CHANNEL=main in /opt/ankibase/backend/.env. From the command line:
curl -fsSL https://raw.githubusercontent.com/Macro002/AnkiBase/main/install.sh | sudo bash -s -- --update- Logins are HttpOnly, SameSite cookies (Secure over HTTPS), kept for 7 days and dropped when a password changes. Failed logins are rate-limited per user and per address.
- Every request checks the user's current permissions and that they may use the profile they're on.
- Secrets are generated on first start (
backend/data/.secrets, mode 0600); API keys are encrypted with them. - Card HTML runs in a sandboxed frame; card text elsewhere is sanitized; images fetched by address can only come from the public internet.
- AnkiBase runs as root (it manages its own services and updates). Put it behind HTTPS (the installer can set up nginx and Let's Encrypt) before exposing it to the internet.
journalctl -u ankibase -f # live logs
systemctl restart ankibase # restart
systemctl status ankibase # status
journalctl -u ankibase-anki -f # Anki engine logsCollections live in /opt/ankibase/anki-data/<profile>/ (Anki's usual layout: collection.anki2,
collection.media/, backups/), with a backup every hour.
Older versions ran one headless Anki container per account (now called profiles). The first
start after updating moves every one to the new engine on its own: it stops each container, copies the
collection and media into /opt/ankibase/anki-data/, carries the AnkiWeb login over and
removes the container. The Docker volumes are left untouched, so delete them yourself once
you're happy (docker volume ls, docker volume rm …).
# backend (http://localhost:8000)
cd backend
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload
# frontend (http://localhost:5173, proxies /api to :8000)
cd frontend
npm install
npm run devBefore opening a PR, run npm run lint and npm run build in frontend/. The docs site lives in docs/ (Nextra) and deploys to GitHub Pages on every push to main.
Project layout
backend/
main.py FastAPI app and API routes
review.py studying through Anki's reviewer, signed media URLs
stats_engine.py Anki + Quizlet statistics
story_generator.py AI providers, stories, reading annotations
dictionary.py dictionary lookups
database.py SQLite: users, profiles, Quizlet sets, sessions, stories
security.py permissions, per-login profiles, secrets, outgoing-request checks
updater.py safe in-app updates (check, back up, install, roll back)
sync_server.py Anki's own sync server, run next to AnkiBase
frontend/src/
components/ Decks, Study, Quizlet modes, Story, Reading, Search, Stats…
components/study/ sandboxed Anki card frame
components/quizlet/ Learn, Test, Match, Blast, Blocks + shared UI
pages/Settings.tsx themes, sync, language, account, AI, users
pages/Setup.tsx first-run wizard
docs/ documentation site (Nextra)
install.sh installer / updater
MIT. AnkiBase is an independent project and isn't affiliated with Anki, AnkiWeb or Quizlet.









