Offline-first MCQ exam and adaptive-study engine with scoring, timers, analytics, weak-topic detection, and question-pack generation.
See the codeAn offline-first MCQ exam and adaptive-study engine that runs in a single HTML file.
Explore the docs · Open ExamEngine · Report a bug · Request a feature
ExamEngine helps learners turn reference material into question packs, take exams offline, and use their results to focus the next study session. It pairs a source-grounded MCQ generator skill with a deterministic browser exam engine.
Implemented in v2:
The current scope is a single-user offline app. Accounts, cloud sync, instructor administration, and remote proctoring are planned extensions, not implemented features. The browser exports adaptive requests; it does not call an AI service to generate questions itself.
See Architecture, the v2 status snapshot dated August 16, 2026, and the Roadmap for more detail.
localStorage for sessions, history, notebook entries, and theme preference.There are no declared npm dependencies and no backend service requirement.
The repository includes a ready-to-open offline viewer and a nine-question Cell Biology sample pack. Node.js and Python are needed only for development or CLI validation.
Use ExamEngine online or save the self-contained HTML to your device for offline use. Hosting is free; no login or payment is required.
Clone the repository and enter its directory:
git clone https://github.com/DagerottDev/ExamEngine.git
cd ExamEngine
Open mcq-exam-website/index.html in your browser. The generated file embeds the styles, JavaScript, and sample pack, so it can run offline without a web server.
No npm install, environment variables, API keys, or external services are required to run the viewer. If you already have the checkout, use its existing directory.
If your browser restricts storage for local files, serve the checkout locally instead:
python3 -m http.server 8000 --bind 127.0.0.1
Then open the local viewer. Keep using the same browser and URL to retain that browser's local history.
To study with immediate feedback, choose Study before loading a pack and use Check answer. Study mode keeps the pack's timing settings; use timing.mode: "none" in a pack for untimed study.
To load your own content, drop a JSON pack onto the upload area or click it to browse. Uploads are limited to 5 MiB. Valid legacy v1 content is migrated for the session; newly generated packs should use schema v2.
Saved unfinished sessions appear on the landing page with Resume and Discard controls. The overall exam deadline continues to elapse while the page is closed. Per-question remaining time is preserved across navigation, so revisiting a question does not grant a fresh timer. When the overall timer expires, the exam submits automatically; when a question timer expires, the viewer moves forward or submits at the last question.
Keyboard shortcuts during a session: ← / → navigate, F marks for review, and A–H select the corresponding option.
Open the repository in your agent environment and invoke the mcq-pack-generator skill. Supply the exact question count, source material, and, when available, two to five representative target-exam questions. Include timing and scoring preferences if needed.
The generator skill is open source under the same MIT license as the app.
In Codex, open the repository and invoke $mcq-pack-generator; in another
compatible agent, load its SKILL.md using that tool's skill mechanism.
To reuse it in another project, copy the entire
.agents/skills/mcq-pack-generator/ directory, including LICENSE, scripts/,
resources/, and examples/. For a copy installed elsewhere, validate with
python3 <skill-folder>/scripts/validate_pack.py <pack.json>.
Generation runs in your own AI tool, separately from the free website. Any AI provider charges depend on your tool and account. You can also author packs manually using the schema; the skill is not required to load a valid JSON pack. Only publish question packs and reference material you have permission to share.
The skill maps sources, calibrates difficulty, plans coverage, generates questions, and checks grounding, distractors, duplicates, answer-position balance, metadata, and marks consistency before validation. Without a sample paper, it uses moderate difficulty and reports that the difficulty was inferred. Its default output directory is mcq-packs/.
Validate any generated or hand-edited pack from the repository root:
python3 .agents/skills/mcq-pack-generator/scripts/validate_pack.py path/to/pack.json
For an adaptive follow-up, supply the exported request and the relevant reference material to the generator. The request contains weak topics, prior wrong/skipped question IDs, subject, source provenance, a count of 15, and a hard target difficulty. Generate new stems, then validate and upload the new pack.
Use the canonical schema and complete sample pack as references. This complete one-question example uses both timers and question-level scoring:
{
"schemaVersion": "2.0",
"exam": {
"title": "Cell Biology Practice",
"subject": "Biology",
"examType": "Practice",
"totalMarks": 1
},
"difficulty": "easy",
"timing": {
"mode": "both",
"examDurationSeconds": 300,
"defaultQuestionSeconds": 60
},
"scoring": { "mode": "question" },
"delivery": {
"mode": "exam",
"shuffleQuestions": false,
"shuffleOptions": false,
"seed": "cell-practice-01"
},
"questions": [
{
"id": 1,
"question": "Ribosomes are composed of which of the following?",
"options": ["RNA and proteins", "DNA and proteins", "Lipids and RNA", "Only proteins"],
"answerIndex": 0,
"marks": 1,
"negativeMarks": 0.25,
"explanation": "Ribosomes are nucleoprotein complexes made of rRNA and proteins.",
"topic": "Cell organelles",
"difficulty": "easy",
"cognitiveLevel": "remember",
"learningObjective": "Recall ribosome composition.",
"sourceRefs": ["cell-unit:p2"],
"tags": ["ribosome", "rRNA"],
"confidence": 0.99
}
]
}
answerIndex; multi-select questions use multiSelect: true and answerIndices, with no answerIndex. Multi-select correctness is exact-set and all-or-nothing.none, exam, question, and both. Per-question limits can override the default with questionTimeSeconds.question and uniform. exam.totalMarks must equal the sum of question marks, or questions.length × scoring.correctMarks for uniform scoring. Uniform scoring also requires scoring.negativeMarks.Sessions, attempt history, theme preference, and the wrong-answer notebook are stored in browser localStorage. ExamEngine does not upload these records to a server. History retains up to 100 attempts and the notebook up to 500 entries; the landing page displays the ten most recent attempts and twenty most recent notebook entries.
Data belongs to the browser profile and origin. It does not automatically follow you across devices, profiles, or between the hosted site, a local file, and a locally served URL. Clearing browser storage removes saved sessions and history. Export results you want to keep.
The hosted page requires a connection to load; the downloaded HTML can run offline. GitHub's hosting service may collect access logs, and selecting source or support links opens an external site. ExamEngine itself does not upload packs or attempts to GitHub or payment providers.
This is a personal-study tool with answers included in its JSON packs. It has no account system, remote proctoring, or server-side assessment integrity controls. Source links in packs may open external pages when selected.
Run commands from the repository root. No dependency installation is needed.
npm run verify
npm run build:check
verify runs the Node core tests, Python validator tests, and sample-pack validation. build:check checks that the committed offline viewer matches the current sources without rewriting it.
After editing source files or the embedded sample, regenerate the distribution:
npm run build
For individual checks, use npm test, npm run test:validator, or npm run validate:sample.
| Path | Purpose |
|---|---|
src/core/exam-engine.js | Validation, migration, seeded delivery, timing, scoring, and analytics |
src/app.js | Browser workflow, persistence, review, retests, and exports |
src/index.html, src/styles.css | Development shell and styles |
scripts/build.mjs | Combines source and sample into the offline HTML file |
mcq-exam-website/ | Generated viewer and sample pack |
schema/ | Canonical v2 JSON Schema |
.agents/skills/mcq-pack-generator/ | Generator workflow, schema copy, examples, and Python validator |
tests/ | Core and validator tests |
docs/ | Architecture, dated project status, and roadmap |
Edit the modular files in src/, then build; direct changes to the generated viewer will be overwritten. For browser development, serve the repository with the local-server command above and open the source shell. The raw source shell needs a server for its JavaScript modules and sample fetch; the generated viewer embeds both.
The CI workflow runs core tests, validator tests, sample validation, and the build on pull requests and pushes to main or goal/**. On successful push runs, it commits and pushes the regenerated viewer if the output changed. Current automated coverage targets core logic and validation; comprehensive browser E2E coverage remains a roadmap item.
After verification, pushes to main also deploy the built viewer to GitHub Pages.
Pull requests and goal/** branches do not deploy. A manual workflow run on
main can redeploy the current version.
ExamEngine uses static GitHub Pages hosting at dagerottdev.github.io/ExamEngine. The app needs no server, database, or paid hosting subscription.
To host your own fork:
main, or run Actions → ExamEngine CI → Run workflow
on main. Tests and validation must pass before deployment.github-pages
deployment. A project site normally uses https://<owner>.github.io/<repo>/.npm run build after changing source files.CI publishes only mcq-exam-website/, including the viewer, sample JSON, and a
license copy. The generator is shared through the source repository and runs in
users' own AI tools.
Use the supplied github.io address to keep hosting at ₹0. A purchased
domain, AI generation, and payment-provider fees are separate optional costs.
GitHub Pages has usage limits and is not intended for paid SaaS or sites primarily
focused on commercial transactions; this app stays free with optional external
support links. See GitHub Pages availability
and usage limits.
The documented roadmap prioritizes browser reliability: E2E workflows, reload/resume timing, accessibility, storage recovery, and large-pack performance. Later phases cover richer adaptive learning, pack authoring, release engineering, and optional hosted/instructor workflows.
These are planned milestones. See the roadmap for scope and exit criteria.
Discuss bugs and proposed changes through repository issues or a pull request. Include the pack, reproduction steps, and browser details for exam-workflow problems. Run npm run verify and npm run build:check before submitting changes; regenerate the viewer when source or sample content changes.
Distributed under the MIT License. This covers the app, documentation, schemas, and author-owned generator skill and examples. The skill includes its own license copy, and the generated HTML embeds the full notice for offline reuse. Third-party source books, papers, and user-supplied material retain their own rights.
ExamEngine is free to use. If it helps your study sessions, you can support its development:
Support is optional. Payments are handled on the providers' websites; their fees and terms apply. Bug reports, contributions, and documentation improvements are welcome too.
Use the ExamEngine repository and issue tracker for project support.
Offline-first MCQ exam and adaptive-study engine with scoring, timers, analytics, weak-topic detection, and question-pack generation.
See the codeAn offline-first MCQ exam and adaptive-study engine that runs in a single HTML file.
Explore the docs · Open ExamEngine · Report a bug · Request a feature
ExamEngine helps learners turn reference material into question packs, take exams offline, and use their results to focus the next study session. It pairs a source-grounded MCQ generator skill with a deterministic browser exam engine.
Implemented in v2:
The current scope is a single-user offline app. Accounts, cloud sync, instructor administration, and remote proctoring are planned extensions, not implemented features. The browser exports adaptive requests; it does not call an AI service to generate questions itself.
See Architecture, the v2 status snapshot dated August 16, 2026, and the Roadmap for more detail.
localStorage for sessions, history, notebook entries, and theme preference.There are no declared npm dependencies and no backend service requirement.
The repository includes a ready-to-open offline viewer and a nine-question Cell Biology sample pack. Node.js and Python are needed only for development or CLI validation.
Use ExamEngine online or save the self-contained HTML to your device for offline use. Hosting is free; no login or payment is required.
Clone the repository and enter its directory:
git clone https://github.com/DagerottDev/ExamEngine.git
cd ExamEngine
Open mcq-exam-website/index.html in your browser. The generated file embeds the styles, JavaScript, and sample pack, so it can run offline without a web server.
No npm install, environment variables, API keys, or external services are required to run the viewer. If you already have the checkout, use its existing directory.
If your browser restricts storage for local files, serve the checkout locally instead:
python3 -m http.server 8000 --bind 127.0.0.1
Then open the local viewer. Keep using the same browser and URL to retain that browser's local history.
To study with immediate feedback, choose Study before loading a pack and use Check answer. Study mode keeps the pack's timing settings; use timing.mode: "none" in a pack for untimed study.
To load your own content, drop a JSON pack onto the upload area or click it to browse. Uploads are limited to 5 MiB. Valid legacy v1 content is migrated for the session; newly generated packs should use schema v2.
Saved unfinished sessions appear on the landing page with Resume and Discard controls. The overall exam deadline continues to elapse while the page is closed. Per-question remaining time is preserved across navigation, so revisiting a question does not grant a fresh timer. When the overall timer expires, the exam submits automatically; when a question timer expires, the viewer moves forward or submits at the last question.
Keyboard shortcuts during a session: ← / → navigate, F marks for review, and A–H select the corresponding option.
Open the repository in your agent environment and invoke the mcq-pack-generator skill. Supply the exact question count, source material, and, when available, two to five representative target-exam questions. Include timing and scoring preferences if needed.
The generator skill is open source under the same MIT license as the app.
In Codex, open the repository and invoke $mcq-pack-generator; in another
compatible agent, load its SKILL.md using that tool's skill mechanism.
To reuse it in another project, copy the entire
.agents/skills/mcq-pack-generator/ directory, including LICENSE, scripts/,
resources/, and examples/. For a copy installed elsewhere, validate with
python3 <skill-folder>/scripts/validate_pack.py <pack.json>.
Generation runs in your own AI tool, separately from the free website. Any AI provider charges depend on your tool and account. You can also author packs manually using the schema; the skill is not required to load a valid JSON pack. Only publish question packs and reference material you have permission to share.
The skill maps sources, calibrates difficulty, plans coverage, generates questions, and checks grounding, distractors, duplicates, answer-position balance, metadata, and marks consistency before validation. Without a sample paper, it uses moderate difficulty and reports that the difficulty was inferred. Its default output directory is mcq-packs/.
Validate any generated or hand-edited pack from the repository root:
python3 .agents/skills/mcq-pack-generator/scripts/validate_pack.py path/to/pack.json
For an adaptive follow-up, supply the exported request and the relevant reference material to the generator. The request contains weak topics, prior wrong/skipped question IDs, subject, source provenance, a count of 15, and a hard target difficulty. Generate new stems, then validate and upload the new pack.
Use the canonical schema and complete sample pack as references. This complete one-question example uses both timers and question-level scoring:
{
"schemaVersion": "2.0",
"exam": {
"title": "Cell Biology Practice",
"subject": "Biology",
"examType": "Practice",
"totalMarks": 1
},
"difficulty": "easy",
"timing": {
"mode": "both",
"examDurationSeconds": 300,
"defaultQuestionSeconds": 60
},
"scoring": { "mode": "question" },
"delivery": {
"mode": "exam",
"shuffleQuestions": false,
"shuffleOptions": false,
"seed": "cell-practice-01"
},
"questions": [
{
"id": 1,
"question": "Ribosomes are composed of which of the following?",
"options": ["RNA and proteins", "DNA and proteins", "Lipids and RNA", "Only proteins"],
"answerIndex": 0,
"marks": 1,
"negativeMarks": 0.25,
"explanation": "Ribosomes are nucleoprotein complexes made of rRNA and proteins.",
"topic": "Cell organelles",
"difficulty": "easy",
"cognitiveLevel": "remember",
"learningObjective": "Recall ribosome composition.",
"sourceRefs": ["cell-unit:p2"],
"tags": ["ribosome", "rRNA"],
"confidence": 0.99
}
]
}
answerIndex; multi-select questions use multiSelect: true and answerIndices, with no answerIndex. Multi-select correctness is exact-set and all-or-nothing.none, exam, question, and both. Per-question limits can override the default with questionTimeSeconds.question and uniform. exam.totalMarks must equal the sum of question marks, or questions.length × scoring.correctMarks for uniform scoring. Uniform scoring also requires scoring.negativeMarks.Sessions, attempt history, theme preference, and the wrong-answer notebook are stored in browser localStorage. ExamEngine does not upload these records to a server. History retains up to 100 attempts and the notebook up to 500 entries; the landing page displays the ten most recent attempts and twenty most recent notebook entries.
Data belongs to the browser profile and origin. It does not automatically follow you across devices, profiles, or between the hosted site, a local file, and a locally served URL. Clearing browser storage removes saved sessions and history. Export results you want to keep.
The hosted page requires a connection to load; the downloaded HTML can run offline. GitHub's hosting service may collect access logs, and selecting source or support links opens an external site. ExamEngine itself does not upload packs or attempts to GitHub or payment providers.
This is a personal-study tool with answers included in its JSON packs. It has no account system, remote proctoring, or server-side assessment integrity controls. Source links in packs may open external pages when selected.
Run commands from the repository root. No dependency installation is needed.
npm run verify
npm run build:check
verify runs the Node core tests, Python validator tests, and sample-pack validation. build:check checks that the committed offline viewer matches the current sources without rewriting it.
After editing source files or the embedded sample, regenerate the distribution:
npm run build
For individual checks, use npm test, npm run test:validator, or npm run validate:sample.
| Path | Purpose |
|---|---|
src/core/exam-engine.js | Validation, migration, seeded delivery, timing, scoring, and analytics |
src/app.js | Browser workflow, persistence, review, retests, and exports |
src/index.html, src/styles.css | Development shell and styles |
scripts/build.mjs | Combines source and sample into the offline HTML file |
mcq-exam-website/ | Generated viewer and sample pack |
schema/ | Canonical v2 JSON Schema |
.agents/skills/mcq-pack-generator/ | Generator workflow, schema copy, examples, and Python validator |
tests/ | Core and validator tests |
docs/ | Architecture, dated project status, and roadmap |
Edit the modular files in src/, then build; direct changes to the generated viewer will be overwritten. For browser development, serve the repository with the local-server command above and open the source shell. The raw source shell needs a server for its JavaScript modules and sample fetch; the generated viewer embeds both.
The CI workflow runs core tests, validator tests, sample validation, and the build on pull requests and pushes to main or goal/**. On successful push runs, it commits and pushes the regenerated viewer if the output changed. Current automated coverage targets core logic and validation; comprehensive browser E2E coverage remains a roadmap item.
After verification, pushes to main also deploy the built viewer to GitHub Pages.
Pull requests and goal/** branches do not deploy. A manual workflow run on
main can redeploy the current version.
ExamEngine uses static GitHub Pages hosting at dagerottdev.github.io/ExamEngine. The app needs no server, database, or paid hosting subscription.
To host your own fork:
main, or run Actions → ExamEngine CI → Run workflow
on main. Tests and validation must pass before deployment.github-pages
deployment. A project site normally uses https://<owner>.github.io/<repo>/.npm run build after changing source files.CI publishes only mcq-exam-website/, including the viewer, sample JSON, and a
license copy. The generator is shared through the source repository and runs in
users' own AI tools.
Use the supplied github.io address to keep hosting at ₹0. A purchased
domain, AI generation, and payment-provider fees are separate optional costs.
GitHub Pages has usage limits and is not intended for paid SaaS or sites primarily
focused on commercial transactions; this app stays free with optional external
support links. See GitHub Pages availability
and usage limits.
The documented roadmap prioritizes browser reliability: E2E workflows, reload/resume timing, accessibility, storage recovery, and large-pack performance. Later phases cover richer adaptive learning, pack authoring, release engineering, and optional hosted/instructor workflows.
These are planned milestones. See the roadmap for scope and exit criteria.
Discuss bugs and proposed changes through repository issues or a pull request. Include the pack, reproduction steps, and browser details for exam-workflow problems. Run npm run verify and npm run build:check before submitting changes; regenerate the viewer when source or sample content changes.
Distributed under the MIT License. This covers the app, documentation, schemas, and author-owned generator skill and examples. The skill includes its own license copy, and the generated HTML embeds the full notice for offline reuse. Third-party source books, papers, and user-supplied material retain their own rights.
ExamEngine is free to use. If it helps your study sessions, you can support its development:
Support is optional. Payments are handled on the providers' websites; their fees and terms apply. Bug reports, contributions, and documentation improvements are welcome too.
Use the ExamEngine repository and issue tracker for project support.