berkeley-classes
Search every Berkeley class from your terminal. Build conflict-free schedules. Watch waitlists.
berkeley-classes is a command-line tool for classes.berkeley.edu. It mirrors the full Schedule of Classes into a local SQLite database so you can search, filter, and reason about Berkeley sections faster than the website. It can also do things the website cannot — like building a conflict-free schedule from a wishlist of courses, or watching a class until a seat opens.
Built by a Berkeley student for Berkeley students.
See it in action
Department overview — one command:
$ berkeley-classes dept COMPSCI --term 'Fall 2026'
Department: COMPSCI (term: Fall 2026)
Sections: 53
Distinct courses: 40
Open seats: 607
Top instructors (by section count):
Instructor Sections
Dan Garcia 6
Armando Fox 4
Josh Grossman 4
Alexei Efros 2
Allon Wagner 2
Side-by-side section comparison with conflict verdict:
$ berkeley-classes compare 29147 29179
Field CCN 29147 CCN 29179
Course COMPSCI 61A LEC 001 COMPSCI 61B LEC 001
Title The Structure and Interpretation of C... Data Structures
Instructors Kay Ousterhout, John DeNero Joshua A Hug, Manuel A Sabin
Days Mo We Fr Mo We Fr
Time 12:00 pm - 12:59 pm 02:00 pm - 02:59 pm
Location Wheeler 150 Wheeler 150
Units 4 4
Open seats 64 0
Overlap on [Mo We Fr] but times do not collide
Build a conflict-free schedule from a wishlist:
$ berkeley-classes schedule build --term 'Fall 2026' \
--course 'COMPSCI 61A' --course 'COMPSCI 70' --course 'ECON 1'
Option 1
COMPSCI 61A LEC #29147 Mo, We, Fr 12:00 pm - 12:59 pm
COMPSCI 70 LEC #29086 Tu, Th 03:30 pm - 04:59 pm
ECON 1 LEC #21923 Mo, We 01:00 pm - 01:59 pm
Find an open seat fast:
$ berkeley-classes open 'COMPSCI 61A' --term 'Fall 2026'
CCN Course Type Sec Open Enrolled Waitlist Cap Days Time
29147 COMPSCI 61A LEC 001 64 0 0 0 Mo, We, Fr 12:00 pm - 12:59 pm
What it does
- Search every section by keyword, instructor, days, time window, units, course level, breadth requirement, open-seats-only, and more — all offline once you sync.
- Build a conflict-free schedule from a list of courses you want.
- Watch a CCN and get pinged when seats open or waitlists shrink.
- Compare two sections side-by-side (instructors, times, locations, enrollment, conflict verdict).
- Department overview — total sections, distinct courses, top instructors, open seats by department.
- Find an instructor across every department in one query.
- What changed? — track new sections, instructor swaps, and enrollment moves since your last sync.
- JSON output on every command (
--agent flag) so you can pipe it into anything.
Install
Requires Go 1.26+.
go install github.com/ish-cs/berkeley-classes-cli/cmd/berkeley-classes@latest
Verify:
berkeley-classes --version
If berkeley-classes isn't found, make sure $(go env GOPATH)/bin (usually ~/go/bin) is on your $PATH.
Quickstart
# 1. Check the live site is reachable
berkeley-classes doctor
# 2. List the current terms
berkeley-classes terms | grep "Fall\|Spring"
# 3. Pull a department offline (one-time, ~30s per dept)
berkeley-classes sync run --term 'Fall 2026' --subject 'Computer Science'
# 4. Search what you just synced
berkeley-classes find --keywords 'CS 61A' --term 'Fall 2026'
# 5. Build a conflict-free schedule
berkeley-classes schedule build --term 'Fall 2026' \
--course 'COMPSCI 61A' \
--course 'MATH 1B' \
--course 'ENGLISH R1A'
Commands
Discovery
| Command |
What it does |
berkeley-classes doctor |
Check live-site reachability + local cache health |
berkeley-classes terms |
List every term (Fall 2026, Spring 2026, …) |
berkeley-classes subjects |
List every subject area (COMPSCI, MATH, …) with section counts |
Local sync (foundation for everything else)
berkeley-classes sync run --term 'Fall 2026' --subject 'Computer Science'
Pulls all sections of one subject in one term into your local SQLite store. Run this once per subject you care about. Re-run anytime to refresh enrollment numbers.
Search
berkeley-classes find --keywords '61A' --term 'Fall 2026'
berkeley-classes find --subject 'Computer Science' --open-only
berkeley-classes find --instructor 'DeNero'
berkeley-classes find --days MWF --after 10am --before 4pm
berkeley-classes find --level upper --units 4
Transcendence — things the website can't do
| Command |
Example |
What it does |
schedule build |
berkeley-classes schedule build --term 'Fall 2026' --course 'COMPSCI 61A' --course 'MATH 1B' |
Builds the first N valid weekly schedules with no time conflicts |
watch <CCN> |
berkeley-classes watch 29147 --interval 5m |
Polls until open seats appear or waitlist changes |
since |
berkeley-classes since --term 'Fall 2026' --hours 24 |
Shows what changed since your last sync (new sections, cancellations, instructor swaps) |
instructor <name> |
berkeley-classes instructor 'DeNero' --term 'Fall 2026' |
Every section an instructor is teaching, across every department |
open <code> |
berkeley-classes open 'COMPSCI 61A' |
Every open section of one course |
conflict <A> <B> |
berkeley-classes conflict 29147 29122 |
Do these two CCNs collide on day-of-week and time? |
compare <A> <B> |
berkeley-classes compare 29147 29179 |
Side-by-side render of two sections with conflict verdict |
dept <code> |
berkeley-classes dept COMPSCI --term 'Fall 2026' |
Department overview: section count, open seats, top instructors |
Recipes
Find every open CS section in Fall 2026:
berkeley-classes find --subject 'Computer Science' --term 'Fall 2026' --open-only
Build a 16-unit Fall schedule:
berkeley-classes schedule build --term 'Fall 2026' \
--course 'COMPSCI 61A' \
--course 'MATH 53' \
--course 'ENGLISH R1A' \
--course 'PHYSICS 7A' \
--max-results 5
Watch CS 161 every 10 minutes:
berkeley-classes watch 29202 --interval 10m
What is DeNero teaching this term?
berkeley-classes instructor 'John DeNero' --term 'Fall 2026'
Department snapshot:
berkeley-classes dept COMPSCI --term 'Fall 2026'
Output modes
- Default: human-readable table.
--json — pretty JSON.
--agent — JSON + compact + no prompts + no color. The mode to use when piping into other tools or LLMs.
--csv — CSV (for table/array responses).
--select id,name,status — pick only the fields you want.
How it works
- Sync scrapes the public
classes.berkeley.edu search pages, parses the section cards, and writes them into a local SQLite database (~/.local/share/berkeley-classes/data.db).
- Queries run against that local DB. Most commands are instant.
- Watch/since keep historical snapshots so they can diff against the last poll.
There is no Berkeley API key required. No login. No private data. Everything berkeley-classes reads is public on classes.berkeley.edu.
Limitations & anti-triggers
- Read-only.
berkeley-classes cannot enroll, drop, or modify your schedule. Use CalCentral for that.
- No grade distributions or RateMyProf data — that's not on
classes.berkeley.edu, so it's not here either. Use berkeleytime.com for grades.
- No historical archive beyond what
classes.berkeley.edu currently exposes.
- Term-scoped: the local store is per-term. Sync the term you want to search.
Automated daily sync (GitHub Actions)
This repo ships a workflow at .github/workflows/sync.yml that runs daily at 09:00 UTC (and on-demand via workflow_dispatch). It syncs the main undergrad subjects for the current term into SQLite, then pushes the result to Supabase via PostgREST.
To enable it on your fork, set two repository secrets under Settings → Secrets and variables → Actions → New repository secret:
SUPABASE_URL — your project URL, e.g. https://abcdefgh.supabase.co
SUPABASE_SERVICE_KEY — the service role key (not the anon key). Required to bypass RLS on upserts.
Trigger a manual run from the Actions tab → Sync Berkeley classes to Supabase → Run workflow.
Contributing
Found a bug? Missing a feature? Open an issue or PR. This is for Berkeley students by a Berkeley student.
git clone https://github.com/ish-cs/berkeley-classes-cli.git
cd berkeley-classes-cli
go test ./...
go build -o berkeley-classes ./cmd/berkeley-classes
License
MIT. See LICENSE.