Open Model Lab is a public-source, simulation-first STEM learning lab for students. It aims to be closer to an interactive science atlas than a generic notes wiki: concepts should be learned by predicting, changing, observing, explaining, and checking real models.
This is the active source repository for Open Model Lab. The code is published under AGPL-3.0-only, the educational content is shared under CC BY-NC-SA 4.0, and the official Open Model Lab name, logos, domains, and brand presentation are reserved under BRAND.md.
It is not a turnkey production deployment package for cloning the official Open Model Lab website. Real production configuration is intentionally absent: real wrangler.jsonc, real public/ads.txt, deployment secrets, vendor accounts, private Stripe/Resend/AdSense/Supabase setup, and private operator history are not included.
Ordinary code, docs, content, test, accessibility, and localization work does not need production vendor setup. Anyone operating an independent fork must use their own name, branding, domains, vendor accounts, keys, legal policies, and deployment process.
This repository is the active source of truth for future public-facing development. See docs/repository-identity.md for the distinction between this repository and the private historical/archive repository.
This repo is no longer the earlier static prototype. The current codebase already includes:
- a structured concept catalog and authored concept-content system
- shared concept-page assembly and simulation renderer seams
- guided collections, starter tracks, challenge flows, and assignment/account surfaces
- local-first progress plus optional signed-in sync
- a canonical
free | premiumentitlement seam - Stripe-hosted billing with webhook-driven entitlement updates
- bounded ad placements on discovery pages only
- server-side feedback/contact delivery with a visible fallback path
- public trust/compliance pages and launch-readiness docs
- Physics-focused today, with broader STEM-friendly branding
- A catalog spanning mechanics, oscillations and waves, optics, electricity, early magnetism/electromagnetism, plus math/chemistry/computer-science entry points
- Simulation-first concept labs with supporting worked examples, review tools, progress cues, and share links
- Signed-out usage stays local-first; signed-in usage can layer on account sync and optional Supporter convenience capabilities
- Public-good contribution lanes are documented in docs/public-good-contribution-lanes.md
- The public site includes a
/sourceposture page for contribution lanes, protected boundaries, and how to send ideas before public issue intake opens.
- The canonical entitlement seam lives in
lib/account/entitlements.ts. - The current internal tier model is still
freeandpremium. - Public copy should emphasize free core learning plus an optional Supporter plan for sustainability and convenience.
- The current Supporter copy model does not change billing, webhook, database, API, or entitlement internals.
- Signed-in free accounts can sync the core progress snapshot.
- The paid convenience layer currently gates:
- saved compare setups
- exact-state sharing and public experiment-card flows
- richer study and review surfaces
- ad-free browsing
- Billing uses Stripe-hosted checkout and billing portal flows. Webhooks update the billing profile and entitlement records.
- Ads are intentionally bounded to discovery surfaces only:
//concepts/concepts/topics/guided
- Concept labs, challenges, pricing, account/auth, contact, and dev harness pages remain ad-free.
- Feedback and contact go through
app/api/feedback/route.tsandlib/feedback-delivery.ts, with direct delivery when configured and an honest public email fallback when not.
This repository starts from a clean release history. Repo-facing preparation and maintenance notes live in:
- Public-source roadmap
- Public-good contribution lanes
- Monetization boundaries
- Public release safety checklist
- Public release hygiene inventory
- GitHub triage guide
- GitHub label setup
- Final public release gate
- Public release history audit
- Repository identity
- Source code is licensed under GNU AGPLv3 only, with package metadata using
AGPL-3.0-only. - Educational content is licensed under CC BY-NC-SA 4.0.
- The Open Model Lab name, logo, icons, domains, and brand assets are all rights reserved under BRAND.md.
- Contribution guidance lives in CONTRIBUTING.md.
- Issue templates live in
.github/ISSUE_TEMPLATE, and the pull request checklist lives in.github/PULL_REQUEST_TEMPLATE.md. - Recommended label definitions live in
.github/labels.yml; setup notes live in docs/github-label-setup.md. - Private vulnerability reporting guidance lives in SECURITY.md.
- Contributor conduct expectations live in CODE_OF_CONDUCT.md.
Private automation/operator internals, old private UX audit PDFs, real wrangler.jsonc, real public/ads.txt, and local translation-memory caches are excluded from this public tree.
- Next.js 16 App Router
- React 19
- TypeScript 5
- Tailwind CSS 4
- Zod for content and payload validation
- Vitest + Testing Library for tests
- Supabase SSR/Auth + Postgres for account/session/sync storage
- Stripe for Supporter billing backed by the existing internal entitlement seam
- OpenNext Cloudflare + Wrangler for preview/deploy flows
app/: App Router routes, API routes, auth/account/billing flows, trust pages, and discovery/learning surfacescomponents/concepts/: shared concept-page framework and concept teaching surfacescomponents/simulations/: simulation shell, renderers, controls, readouts, and concept-specific simulation modulescomponents/progress/,components/account/,components/share/,components/ads/: learner-state, account, share, and ad UI seamscontent/catalog/: canonical concept, topic, track, challenge, and guided metadatacontent/concepts/: authored rich concept contentlib/content/: schemas, loaders, generated registry, and content selectorslib/progress/: local progress model, selectors, continue-learning state, and sync adapterslib/account/: session resolution, entitlement derivation, dev harness, and account storage helperslib/billing/: Stripe checkout, portal, webhook, and billing-profile helperslib/ads/: ad placement policy, provider config, and placement resolutionlib/share-links.ts: exact-state and share-link helperslib/feedback*.ts: feedback payload shaping, rate limiting, and deliverytests/: account, ads, billing, app routes, content, learning, progress, feedback, metadata, and share-link coveragesupabase/migrations/: current account sync, entitlement, and billing-profile tablesdocs/: content authoring, concept framework, account-sync local setup, feedback triage, and launch-readiness docs
Use Node 20.x and pnpm 10.x (see .node-version, .nvmrc, packageManager, and engines).
pnpm install
pnpm devOpen http://localhost:3000.
No production vendor accounts are needed for ordinary code, docs, content, accessibility, localization, or test contributions.
The content registry is regenerated automatically before dev, lint, test, build, preview, and deploy commands. If you are working directly on content/catalog files and need to refresh it manually, run:
pnpm content:registryMost contributors only need pnpm install, pnpm dev, and the validation commands below. The deterministic dev harness is available for local account-state QA without real vendor accounts: enable ENABLE_DEV_ACCOUNT_HARNESS=true and use /dev/account-harness.
Vendor setup docs are for maintainers/operators of the official deployment, or for independent fork operators using their own accounts and branding. They are not instructions for deploying an official Open Model Lab clone.
- For Supabase auth, progress sync, entitlement rows, and magic-link redirect setup, see docs/account-sync-local-setup.md.
- For launch-sensitive env vars and manual vendor steps for Stripe, AdSense, Resend, metadata, and trust pages, see docs/launch-readiness.md.
- For Cloudflare preview/deploy work, provide private Wrangler config through
OPEN_MODEL_LAB_WRANGLER_JSONC_CONTENTorOPEN_MODEL_LAB_WRANGLER_JSONC_SOURCE, then runpnpm wrangler:checkandpnpm deploy:preparein the private deploy environment. Workers Builds should run OpenNext after that preparation, not plainpnpm build; use the explicit drawer commands orpnpm cloudflare:buildfrom docs/launch-readiness.md. The helper writes ignoredwrangler.jsoncwithout printing the config. - For AdSense on an independently operated deployment, keep the real
public/ads.txtprivate and ignored. Usepublic/ads.example.txtas the format reference andpnpm ads:writeto materialize the real file from private env or a private source file.
Fork operators are responsible for their own Supabase project, Stripe products/prices/webhooks, Resend sender/domain setup, AdSense account/slot IDs/consent obligations, Cloudflare configuration, legal policies, and brand compliance.
Run the smallest truthful lane for the change, then broaden before release-sensitive changes.
pnpm lint
pnpm typecheck
pnpm test
pnpm content:doctor
pnpm public-release:hygiene
pnpm public-release:final-check
pnpm public-release:history-auditpnpm typecheck is important here: the current Next build config skips TypeScript build errors, so pnpm build is not a substitute for a real typecheck.
Good first public issues should be small, student-facing, and easy to verify:
- concept corrections: definitions, units, graph labels, worked examples, or misconception notes;
- accessibility and contrast fixes on concept benches;
- clearer student-facing instructions for predict/change/observe/explain loops;
- small tests for content schemas, route behavior, or simulation controls;
- docs that make no-vendor local contribution easier.
See docs/public-good-contribution-lanes.md for owner-decision boundaries and issue seeds.
/concepts/concepts/topics/guided/tracks/challenges/pricing/account/contact/privacy/terms/ads/dev/account-harnesswhen enabled locally