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

IELTS Atlas: a self-hosted IELTS reading and listening practice app you run yourself

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

1,709 stars175 forksJavaScriptGPL-3.0

At a glance

What is it?
IELTS Atlas (sallowayma-git/IELTS-practice) is a pure front-end IELTS reading and optional listening practice system that runs from index.html, stores records in IndexedDB, and expects you to supply and keep your own question banks. Here is how it installs, what it does with your data, and where it stops working.
Who is it for?
IELTS Atlas fits people who want an offline, self-controlled IELTS reading drill with score history, and who are willing to supply their own question bank and keep the deployment private. It is the wrong tool if you want a ready-made listening library, a phone-first experience, or a single-file copy you can email around.
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 received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

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

Editorial analysis

What IELTS Atlas actually solves, and for whom

Most IELTS practice sites are someone else's server. You get an account, a paywall or a login, and your answer history lives in a database you cannot read. IELTS Atlas inverts that. The README describes it as a pure front-end system whose main entry is index.html, running on static HTML, CSS, a JavaScript bundle and local question bank assets, with no backend service required. Practice data defaults to browser local storage, and the README states the app can run directly under the file:// protocol or be deployed to static web hosting.

The audience is narrow and specific. It is for a learner who already has reading materials and wants a drill interface with scoring, wrong-answer analysis, statistics and backup on top of them. The README is explicit that the public repository and ordinary release packages do not include listening audio, accompanying question sources, PDFs, a complete ListeningPractice/ directory, or a pre-generated listening index. Listening is an optional local extension the user assembles. The README also states that the question sources and some materials carry third-party copyright risk, and asks users to deploy privately, keep distribution controlled, and not sell or promote anything built on it. That is a usage constraint, not a feature, and it shapes who this is for: someone comfortable keeping a private deployment rather than publishing a study site.

How the reading and listening flows are wired together

The architecture is three layers: static pages, generated assets, and browser storage. Reading practice runs through a unified reading page and draws on two generated asset directories, assets/generated/reading-exams/ and assets/generated/reading-explanations/. The README states that the default reading index comes from generated assets under assets/generated/ and that the index should not be hand-maintained. Practice itself opens in a separate window and communicates back to the main window through postMessage; the README lists window.open and postMessage among the required browser capabilities. Answers, correct answers, scores and question context travel back over that channel and are written into local history.

Listening follows the same shape but with a bridge. A listening index and a record bridge module feed results into the same record system as reading, and the README names listening-record-bridge as the component that converts listening results into unified practice records. The expected extension paths are assets/generated/listening-exams/manifest.js and assets/generated/listening-exams/listening-index.compat.js, with a P1-P4 directory structure. Those paths describe where extension resources belong. If they are absent from a public package, the README says that is expected behaviour rather than a missing repository file.

Persistence is deliberately strict. Core data lives in IndexedDB, and the README states that when IndexedDB is unavailable the app reports an explicit error instead of silently falling back to weaker storage. localStorage is kept for legacy migration and small compatibility state, sessionStorage for session-level drafts. Data is isolated per browser, per protocol and per origin, which is why a file:// session and a http://localhost session do not see each other's records.

Installing IELTS Atlas and finishing one reading item

There is no package manager step. The README's local run instructions are: download or unpack the full project directory, keep the directory structure intact rather than copying index.html alone, then open index.html in the root directory. The README notes that index.html is currently the only entry point and that improved-working-system.html, which appeared in older documentation, is no longer valid. Chrome or Edge stable is recommended; ES6, IndexedDB, localStorage, sessionStorage, window.open and postMessage are the required capabilities. Firefox, Safari and mobile browsers work but the README warns that file://, PDF, audio, cross-window communication and popup policies may be stricter there.

If the browser restricts file:// resource access, the README suggests a static server from the project root:

bash
python -m http.server 8000

After that, http://localhost:8000/ serves the app. The README frames the local server as useful for debugging resource paths, console errors, and PDF or audio loading problems, and still expects a distributed personal package to open index.html directly after unpacking.

The first real use is a single reading item. Open index.html, go to 题库浏览 and confirm the question list renders. Use the type filter, the P1/P2/P3 category filter or the search box to locate a passage, then click the practice entry on the card. A new window opens, so the browser must be allowed to show popups; the README states that popups must be permitted on first practice or the practice window may not open. Answer and submit in that window, then return to the main window and check 练习记录 for the saved result. If the window opened but no score was saved, the README points at popup permissions, console errors and postMessage state, in that order.

Where the popup and window model breaks down

The cross-window design is the source of most failure modes, and the README is candid about it. Practice depends on new browser windows and postMessage, so a blocked popup, a closed practice window or an interrupted session pushes the system into a degraded save path. In set practice mode, which chains several items into one aggregated 套题 record, the README warns against running the same set in parallel across multiple browser windows, because window references, state synchronisation and record merging all become harder to reconcile.

Data durability is the second boundary. Practice records are the core user data, and the README lists clearing cache, switching browsers, private mode and automatic site-data cleanup as things that can affect record persistence. IndexedDB being unavailable is a hard stop rather than a graceful degradation. The 清除全部本地数据 action in settings deletes practice, question bank, vocabulary, settings, in-app backups and local folder bindings, and returns the app to first launch with the GPL agreement shown again; JSON backups in external folders are not deleted. There is no documented server-side sync on the main branch, so recovery depends on backups you made yourself.

Matching is the third boundary. The README states that custom question banks should keep a stable directory structure, and that frequently moving files, renaming directories or mixing question banks from different sources can cause records and question indexes to stop matching accurately. Import is also a browser-side scan and standardisation process, so a very large local bank is bounded by what the browser can index.

Branches, and the server-backed alternative

The repository maintains three branches with different trade-offs, and the choice matters more than any single feature. main is the static web version on pure front end, described as stable and 95% complete, compatible with nearly all devices. feature/multi-device-easy-deploy is a self-hosted server version built on Node.js, described as stable and 100% complete, aimed at users with some software background who want data synchronisation across devices. IELTS-WRITING-FEAT is an AI-native collaboration client with writing scoring, a reading coach and self-evolution features, listed as in development at 80% complete. A related repository, IELTS-Project (IELTMPS), is described as an integrated solution for an independent web server covering backend, routing, database and security infrastructure, built on Docker Compose and PostgreSQL, and is also listed as in development.

The practical difference is where your records live. main keeps everything in the browser and gives you no synchronisation; moving to another device means using 导出数据 to produce a JSON file and 导入数据 to restore or merge it, followed by the built-in integrity check. The Node.js branch exists precisely because that manual loop is inconvenient. If you want a phone and a laptop to share history without exporting files, main is the wrong branch, and the README's own branch table points you elsewhere.

Licence, maintenance and the cost of upgrading

The code is licensed under GPL-3.0, per the LICENSE file and the repository metadata. The README separates this from content rights: question sources, articles, audio, PDFs, images and other third-party content remain with their original rights holders and are recommended only for personal study and exam preparation. Running the software and redistributing a package that bundles question sources are therefore different acts, and the README asks users not to keep publicly distributing sites, mirrors, archives or modified pages that contain question sources. This is not legal advice; if you plan anything beyond private use, read the LICENSE and the usage statement yourself and take your own view.

The last push to the repository was on 2026-09-10, and the most recent release is v0.6.3 from 2026-08-09, following v0.6.2-fix and v0.6.2. The repository is not archived. Upgrade cost is mostly about assets rather than code. Because the reading index comes from generated assets under assets/generated/ and should not be hand-maintained, a version bump can mean regenerating or replacing those assets, and the README's 强制刷新题库 action exists to re-sync the index, statistics and interface state afterwards. If you have imported your own bank, that import is a separate configuration from the default one, and 题库配置切换 is where you choose which configuration is active. Back up before upgrading, since the settings page's 清除全部本地数据 removes in-app backups too.

Editorial conclusion

IELTS Atlas fits people who want an offline, self-controlled IELTS reading drill with score history, and who are willing to supply their own question bank and keep the deployment private. It is the wrong tool if you want a ready-made listening library, a phone-first experience, or a single-file copy you can email around. Before committing, open index.html from a real folder, confirm the question bank list renders in 题库浏览, allow popups, and finish one reading item end to end to check that the record lands in 练习记录.

Frequently asked questions

How do I take an IELTS practice test with IELTS Atlas?

Open index.html, go to 题库浏览, locate an item with the filters or search box, and click its practice entry. Allow popups for the page, because the README states the practice window may not open otherwise. Submit in the new window and check 练习记录 in the main window for the saved result.

What is an IELTS practice test in IELTS Atlas?

It is a reading item opened in a separate window from the question bank, answered and submitted there, with answers, correct answers, scores and question context sent back to the main window. The README also describes a set practice mode that chains several items into one aggregated record.

Does IELTS Atlas need a server or a database?

The main branch does not. The README describes it as pure front end running on static HTML, CSS, a JavaScript bundle and local question bank assets, with data kept in browser IndexedDB. A separate Node.js branch exists for self-hosted multi-device synchronisation.

Can I use my own IELTS question bank with IELTS Atlas?

Yes. The settings page has a 加载题库 entry that imports reading or listening directories through a folder picker, with a full or incremental choice. The README warns that a stable directory structure matters, because moving files or mixing banks from different sources can break matching between records and the question index.

Why is the listening list empty in IELTS Atlas?

The README states that public repositories and ordinary release packages do not include listening audio, accompanying question sources, PDFs, a full ListeningPractice/ directory or a pre-generated listening index, for copyright reasons. Listening is an optional local extension you prepare yourself.

How do I move IELTS Atlas practice records to another device?

Use 导出数据 in the settings page to produce an external JSON file, then 导入数据 in the new environment to restore or merge it, and run the built-in integrity check. Because data is isolated per browser and origin, a file:// session and a localhost session do not share records.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. README
  4. Releases
  5. sallowayma-git/IELTS-practice on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sallowayma-git-ielts-practice.svg)](https://hysenlabs.com/projects/sallowayma-git-ielts-practice)