A course planner for Monash students, built by the Monash Association of Coding.
Built to replace MonPlan, which Monash sunset on 2 June 2026.
MonMap lets you drag units onto a year-by-year grid and see, in real time, whether your plan works. It checks prerequisites and offerings against the Monash handbook, flags what doesn't fit, shows what your course requirements still need, and keeps a running WAM. Every unit, course and major also has its own page with student reviews and a requisite map. Sign in to save plans across devices, or use it anonymously (the plan stays in your browser) and export it to CSV.
- Quick unit search. Two-pane layout with slot-fit hints and suggestions from your course, so common picks are one click away.
- Student reviews. Rate units, courses and majors on teaching, content, assessment, difficulty and workload. Reviews show initials only, and a classifier screens out abuse, spam and personal details (how it works).
- Handbook pages and search. A page for every unit, course and area of study from 2020 to 2027, with a requisite map of what each unit needs and unlocks, and one search over all of them (details).
- Plans you own. Export to CSV or print. Your data travels with you.
- Faithful handbook coverage. Cross-year prereqs, honours track variations, and the trickier offering rules are all modelled explicitly.
- Open source. If something looks off for your course, read the code, file an issue, or send a PR.
Just visit monmap.monashcoding.com. No account required to start planning; sign in with your Monash Google account to sync across devices.
PRs welcome. If you're a Monash student and something feels off about how a unit, prereq, or course is rendered, that's almost always a bug worth filing. Open an issue with the unit code and what you expected. For non-code feedback there's a Feedback form linked in the app.
Single Next.js app backed by a local Postgres copy of the Monash handbook. The handbook data is published as a tarball on GitHub Releases, so you don't need scraper credentials to spin up a working instance.
- Node ≥ 22 (tested on 25.8)
- pnpm ≥ 10
- Postgres ≥ 14 running locally
# 1. Install workspace deps
pnpm install
# 2. Configure env at the repo root (one .env, see CLAUDE.md §1)
cp .env.example .env
# Edit DATABASE_URL if your Postgres isn't on localhost:5432/monmap
# 3. Create the database and apply migrations
createdb monmap
pnpm db:migrate
# 4. Download the latest handbook corpus from GitHub releases
# (~120 MB; covers 2020–2026, the live site also has 2027).
# Requires the gh CLI; alternatively
# grab it from https://github.com/monashcoding/monmap/releases/latest
gh release download --repo monashcoding/monmap --pattern 'monmap-handbook-*.tar.gz'
# 5. Unpack into the scraper data directory
mkdir -p packages/scraper/data
tar -xzf monmap-handbook-*.tar.gz -C packages/scraper/data
# 6. Load every year into Postgres (~37k units, ~3k courses, ~70k
# offerings across 7 academic years)
pnpm ingest:allpnpm --filter webapp dev # http://localhost:3000On localhost you can't use your real MAC login: the shared
.monashcoding.com session cookie is never sent to localhost, so the
server renders you as signed out (the avatar may still show, because the
browser asks auth.monashcoding.com directly). To sign in locally, serve
the app from a monashcoding.com hostname instead:
-
Point
local.monashcoding.comat your machine. Add these lines to/etc/hosts(needssudo). The IPv6 line matters: without it the system still gets Cloudflare's IPv6 address from public DNS (the*.monashcoding.comwildcard), and browsers try IPv6 first.127.0.0.1 local.monashcoding.com ::1 local.monashcoding.com -
Run the HTTPS dev server and open https://local.monashcoding.com:3000:
pnpm dev:sso
The first run creates a local certificate authority with
mkcertand may ask for your password to trust it. The certificate lands inpackages/webapp/certificates/, which is git-ignored.
The auth service must list https://local.monashcoding.com:3000 in its
TRUSTED_ORIGINS setting (monashcoding/mac-auth). Its built-in
https://*.monashcoding.com wildcard does not match an origin with a
port, so without that entry sign-in and sign-out fail with "Invalid
origin" even though the session still shows.
Signed in this way, you read and write your real plans in whatever
database DATABASE_URL points at.
pnpm db:generate # after editing schema.ts, write a new migration
pnpm db:migrate # apply pending migrations
pnpm db:studio # open drizzle-kit's db browser
pnpm --filter webapp test # pure-function unit tests (node --test)
pnpm --filter webapp typecheck
pnpm lint # eslint over the webapp
pnpm ingest # load a single year (default 2026) from ./packages/scraper/data
pnpm ingest:all # load every year present in the data dirCI (the verify job in .github/workflows/deploy.yml) runs pnpm lint,
pnpm typecheck, pnpm test and a critical-advisory pnpm audit on
every pull request and push to main that changes a package, the
Dockerfile or the root workspace files. On main it then builds the
Docker image, but only when the checks pass.
drizzle-kit pushis deliberately not wired up. Schema changes go throughdb:generate+db:migrateso the history stays auditable (CLAUDE.md §2).
The corpus on GitHub Releases is the canonical source for everyone's local Postgres. To refresh it, re-scrape from CourseLoop and pack the result:
pnpm scrape:all # fetch every published year (slow, hours)
pnpm package # roll monmap-handbook-YYYYMMDD.tar.gz
gh release create handbook-YYYYMMDD monmap-handbook-YYYYMMDD.tar.gz \
--title "Handbook snapshot: YYYY-YYYY (Month YYYY)"- Repo-wide conventions:
CLAUDE.md. - Handbook data quirks (fields that silently lie, JSONB tree shapes,
cross-year references):
docs/handbook-internals.md. Worth skimming before writing a query. - Handbook pages, search and caching:
docs/handbook-pages.md. - Reviews and moderation:
docs/reviews.md. - SEO:
docs/seo.md.
Built and maintained by the MAC Projects team at the Monash Association of Coding.
Thanks to the MAC committee for backing the project, every Monash student who's filed a bug or sent a screenshot, and the maintainers of the open-source libraries we lean on.
AGPL-3.0-only. If you run a modified version of MonMap as a network service, you must make your source available to its users. Internal forks and private experimentation are fine; redistributing or hosting a modified copy means publishing your changes under the same license.
