Self-hosted service
sallowayma-git/IELTS-practice avatar
sallowayma-git/IELTS-practice

IELTS Practice: a file:// exam runner that stores everything in IndexedDB

雅思阅读与听力练习系统,支持题库浏览、套题练习、成绩记录、错题分析、数据备份与本地题库导入。

1,435 stars148 forksJavaScriptGPL-3.0

At a glance

What is it?
IELTS Atlas is a GPL-3.0, JavaScript-only IELTS reading and listening practice system that runs from a single index.html with no backend. Its architecture is a set of cross-window practice pages writing records into IndexedDB, and that window boundary is where most of its behaviour and most of its failure modes live.
Who is it for?
Adopt it if you want a personal, offline IELTS reading runner where the question bank and the record store both stay on your own machine, and you accept that practice happens in a popup window. Do not adopt it if you need multi-device sync out of the box (that lives on the separate feature/multi-device-easy-deploy branch), if you intend to publish a question bank publicly, or if your browser blocks popups or restricts file:// resource access.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

A static exam runner for one person's question bank

The stated problem is narrow and practical: run IELTS reading practice, optionally listening, from a browser with no server. The README describes the main branch as 纯前端运行, compatible with almost any device, and the entry point as a single index.html. Around that entry point sit question bank browsing, reading practice, optional listening practice, full-paper sessions, practice records, statistics, wrong-answer analysis, data backup, question bank import, vocabulary review, answer-review mode and an achievement system.

The intended user is a self-hoster, not a class. The usage notice at the top of the README asks for local runs, private deployments or personal web space, and explicitly asks that sites, mirrors, archives and packaged builds containing question sources, audio, PDFs or explanations not be redistributed further. It also rules out commercial sale, paid communities, traffic funnelling and public promotion. So the audience is a single candidate or a small group who supply their own material and keep the deployment private.

Windows, postMessage and IndexedDB as the data path

The mechanism is unusual enough to be the first thing to understand. Reading practice does not render inside the main page. The question bank card opens a practice window, that window handles answering, submission and result display, then sends the user's answers, correct answers, score and question context back to the main window. The README states that reading practice depends on a browser new window and cross-window communication, and that if the practice page opens but the score is not saved, popup permissions, console errors and postMessage state are the first things to check.

Persistence is IndexedDB. The README is explicit that core persistent data uses IndexedDB and that when IndexedDB is unavailable the application raises a clear error rather than silently falling back to weaker storage. localStorage is kept for legacy migration and a small amount of compatibility state; sessionStorage holds session-level drafts. Data is isolated per browser, per protocol and per origin, which means a file:// run and a localhost run do not see each other's records.

Full-paper mode extends the same model. A session is created, items are opened and switched in sequence, and each sub-item's score, elapsed time and result are aggregated into a single paper record. The README notes a degraded save path when the browser blocks popups or the user closes the practice window manually, and says the system tries to retain completed records after an abnormal close or partial completion. That is a design acknowledgement that the window boundary is fragile.

Running it from a folder or a static host

The quickest path is to download or unpack the full project directory, keep the directory structure intact, and open index.html by double-clicking it. The README warns against copying index.html alone. It also states that improved-working-system.html, which appeared in older documentation, is no longer a valid entry point.

If file:// restrictions get in the way, the documented fallback is a static server from the project root:

python -m http.server 8000

then http://localhost:8000/. The README recommends this for debugging resource paths, console errors, and PDF or audio loading, while noting that a distribution package should still open directly from index.html after unpacking.

Two settings matter on first use. Popups must be allowed, otherwise the practice window may not open. Chrome or Edge current stable is the recommended browser; the README states that ES6, IndexedDB, localStorage, sessionStorage, window.open and postMessage are the baseline capabilities. Firefox, Safari and mobile browsers work, but the README says their restrictions on file://, PDF, audio, cross-window communication and popup policy may be stricter. Static hosting is possible provided the directory hierarchy is preserved so that bundles, question banks, fonts, images, PDFs, audio and generated assets do not 404.

Question bank import, and why the index is generated

The 设置 page carries the maintenance controls: 加载题库 for importing reading or listening directories through a folder picker, 题库配置切换 for switching between the default and imported configurations, and 强制刷新题库 for resynchronising the index and interface state. The README is direct that the question bank index should not be hand-maintained. The default reading index comes from generated assets under assets/generated/, and the listening index is an optional local extension produced by a browser-side scan and normalisation pass when a user imports a bank.

That has a practical consequence. The README warns that custom banks should keep a stable directory structure, and that frequently moving files, renaming directories or mixing banks from different sources can leave records and question indices unable to match accurately. Import is therefore not a one-off action you can forget about; the folder layout is part of the record identity.

Reading assets live at assets/generated/reading-exams/ and assets/generated/reading-explanations/. Listening, if you enable it, expects assets/generated/listening-exams/manifest.js and assets/generated/listening-exams/listening-index.compat.js. The README states that public packages deliberately omit listening audio, accompanying question sources, PDFs, the full ListeningPractice/ directory and pre-generated listening indices, and that their absence is expected rather than a repository defect. To include ListeningPractice/P1-P4 in a personal package you prepare the resources locally and pack with INCLUDE_LOCAL_LISTENING=1. Results from listening flow through listening-record-bridge into the same record system as reading.

The popup dependency is the real failure mode

Most of the sharp edges trace back to one decision: practice runs in a separate window and reports back by postMessage. Popup blockers stop the session before it starts. A user who closes the practice window mid-paper pushes the system into its degraded save path. The README states plainly that full-paper mode is not suited to running the same paper in several browser windows in parallel, because that increases the complexity of window references, state synchronisation and record merging.

Data durability is the second edge. Practice records are the core user data, and the README lists cache clearing, switching browsers, private mode and automatic site-data cleanup as things that can affect persistence. It recommends periodic export or backup from the settings page. The backup model has a boundary worth noting: 清除全部本地数据 removes practice, question bank, vocabulary, settings, in-app backups and local folder bindings, and after a refresh the app returns to first launch and shows the GPL notice again, but JSON backups in external folders are not deleted. Backups only survive if you exported them out of the browser.

The third edge is scope. Listening is an optional local extension with no bundled audio, so a fresh clone gives you a reading system. If your preparation depends on listening, the repository is a scaffold you have to fill.

How it differs from a server-backed IELTS platform

The README points to a related repository, IELTS-Project (IELTMPS), described as an integrated solution for an independent web server covering backend, routing, database and security infrastructure, with Docker Compose and PostgreSQL listed as its technical characteristics and a status of in development. That is the clearest contrast available in the material, and the difference is architectural rather than cosmetic.

IELTS Atlas keeps state in the browser's IndexedDB and treats the origin as the account boundary; there is no server to authenticate against, no shared database and no cross-device sync on the main branch. A server-backed platform puts records in PostgreSQL behind an application tier, which is what makes multi-user access, central backup and device-independent progress possible, at the cost of running and securing that tier. The README also lists a third branch, feature/multi-device-easy-deploy, described as a self-hosted server version with multi-device data sync for users with some software background, and a fourth, IELTS-WRITING-FEAT, described as an AI-native collaborative client in development with writing scoring, a reading coach and self-evolution features. So the project's own answer to the sync gap is a different branch, not the main one.

Licence, maintenance and what a fork inherits

The code is GPL-3.0, and the README states that the code licence is governed by the LICENSE file while question sources, articles, audio, PDFs, images and other third-party content remain with their original rights holders and are recommended for personal study and exam preparation only. There is no legal advice to give here, but the practical split matters: the licence covers the code, and it does not cover the material you feed into it. The usage notice adds that question sources and some assets carry third-party copyright risk, and that public deployment in the form of a computer-based-test web page may touch the interests of practitioners in that field, with wide distribution raising the risk of complaints, takedowns and repository removal.

On maintenance, the visible signal is activity rather than stability: releases v0.6.2, v0.6.2-fix and v0.6.3 land between late May and early August 2026, and the last push to the default branch is 2026-09-10. The README labels the main branch stable at 95 percent completion and the multi-device branch at 100 percent, with the AI branch at 80 percent and in development. The upgrade cost sits in the data layer and the import contract. Because records match questions by index and directory structure, a fork that reorganises assets/generated/ or renames imported bank folders risks orphaning existing records. The settings page's 完整性检查 and 导出数据 are the tools the README offers for validating imported and local data before you rely on it.

Editorial conclusion

Adopt it if you want a personal, offline IELTS reading runner where the question bank and the record store both stay on your own machine, and you accept that practice happens in a popup window. Do not adopt it if you need multi-device sync out of the box (that lives on the separate feature/multi-device-easy-deploy branch), if you intend to publish a question bank publicly, or if your browser blocks popups or restricts file:// resource access. Before committing, open index.html, confirm the question bank list renders under 题库浏览, complete one reading item, and check that a record appears in 练习记录; then run the 设置 page's 完整性检查 against an exported JSON file to confirm the data layer behaves on your browser.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. README
  4. Releases
  5. sallowayma-git/IELTS-practice on GitHub
Community notes

Community notes