coursecast
v0.5.0
Published
One prompt → a full interactive course — live widgets, quizzes, a mastery dashboard — rendered to self-contained HTML and deployed live.
Maintainers
Readme
coursecast
One prompt → a full interactive course. Real multi-lesson content with live widgets, quizzes, a custom simulation per lesson, and a mastery dashboard — rendered to self-contained HTML you can open from disk or deploy anywhere with one command.
Prefer zero setup? The hosted version lives at trycoursecast.com — type a topic in the browser and it generates and hosts the course for you.
Install
npm i -g coursecast # or: npx coursecast …Requires Node 18+.
Use
# a whole course (~12 lessons + mastery dashboard), from one prompt
coursecast "how DNS works"
# generate and deploy live to your own Vercel
coursecast "intro to nuclear power" --deployOpen the printed index.html — that's the whole product: no server, no build step,
works offline, progress saved in the browser.
Engines
The engine is what writes the content. Pick with --engine:
| Engine | Runs on | Needs |
|---|---|---|
| claude (default) | your Claude Code CLI | claude on PATH |
| codex | your Codex CLI | codex on PATH |
| gemini-cli | your Gemini CLI login | gemini on PATH — no API key |
| gemini | the Gemini API, search-grounded | GEMINI_API_KEY (free key) + your --model choice |
coursecast "learn rust" --engine gemini --model gemini-3.5-flash-liteThe gemini engine never picks a model for you — pass --model (or set GEMINI_MODEL) with
whatever your key has access to. COURSECAST_RESEARCH=0 skips the web-search research pass.
All flags
--engine <id> claude (default) | gemini | codex
--model <id> model hint passed to the engine
--storage <id> progress storage: local (default) | cloud
--provider <id> deploy target: vercel | netlify | cloudflare (auto-detected)
--lessons <n> (course) target number of lessons (default ~12)
--concurrency <n> (course) parallel lesson generation (default 4)
--deploy deploy after generating
--dry-run with --deploy, print the deploy command without running it
--preview deploy as a preview instead of production
--out <dir> output directory (default ./out/<slug>)Progress sync
By default a course keeps progress in the browser's localStorage — no server, no account.
--storage cloud adds cross-device sync using your host's own database. Nothing is sent
to coursecast; the deployed course talks only to its own origin, and the data is yours.
| --provider | Storage used | Setup |
|---|---|---|
| netlify | Netlify Blobs | none — works on deploy |
| cloudflare | Workers KV | wrangler kv namespace create PROGRESS, bind it as PROGRESS |
| vercel | Vercel Blob | create a Blob store on the project (token is injected for you) |
coursecast "how dns works" --storage cloud --provider netlify --deploy--provider is required with --storage cloud — including alongside --deploy. Each
host needs a different one-time setup, so picking one for you would leave you owing a
step nobody mentioned, and the symptom is a course that deploys, looks correct, and
quietly never syncs. (--provider stays optional for a plain --deploy: guessing a
deploy target wrong is immediately obvious.)
The page mints a sync code on first use and shows it in the footer. Enter that code on another device to pick up where you left off. No email, no password, nothing personal stored.
Deploy providers
--deploy ships the output directory with your own vercel, netlify or wrangler
(Cloudflare Pages) CLI — whichever you are already logged into, auto-detected —
your account, your URL, no middleman. Or skip it and host the files anywhere that
serves static HTML. Add a provider via src/providers/<id>.mjs exporting name,
isAvailable(), and async deploy({ dir, prod, dryRun }).
Architecture
engine produces a content object (data) → render.mjs turns it into polished
interactive HTML (presentation) → provider deploys the folder. Content and
presentation are separated, so every lesson looks like one product no matter which
engine wrote it. Progress (checklist, quiz, theme) saves per-device in localStorage.
Writing an engine
An engine module exports name, async generateLesson({ topic, slug, model, context }),
and — required for whole courses — async generateSyllabus({ topic, lessons, model }).
Drop it in src/engines/<id>.mjs and pass --engine <id>. See src/engines/stub.mjs
for the minimal shape and src/engines/shared-prompts.mjs for the content contract.
License
MIT © Tomas Sestak
