You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Migrate Highcharts from its current Python entry (highcharts-core wrapper) to a native JavaScript entry, executed as a deprecation window so existing links don't break. This is Phase 2 of docs/concepts/library-expansion.md and the second of three issues splitting the JavaScript rollout:
This issue — Highcharts Python → JavaScript migration (Phase 2).
(third issue) — MUI X Charts (React, framework path).
This is a meta / infrastructure issue, not a spec request — do not apply the spec-request label.
Depends on #8241. This issue reuses the javascript language entry, the Node + Playwright render harness, the framework metadata field, the per-library extension handling, and all the workflow/frontend/backend plumbing stood up there. Do not start until #8241 has merged (or land it as a stacked PR on the same branch).
Why move it
Per docs/concepts/library-expansion.md §6 (the "most-used variant" rule) and §1:
| 8 | Highcharts | JavaScript | Python | JavaScript | npm ~1 M / wk vs highcharts-core ~5 k / wk |
The native highcharts.js outweighs the Python highcharts-core wrapper by ~200× weekly downloads — far past the ≥ 3× threshold — so the rule mandates the canonical entry move to JavaScript. Highcharts is the industry standard in finance/news dashboards; the JS audience is who actually uses it.
License note (unchanged): Commercial, free for non-commercial use. Keep the license tag and surface it prominently on the plot pages — same as today.
The careful bit: deprecation window (§6 + §9)
§6's "Exception — deprecation window": when a library moves languages, both entries may co-exist for one release cycle so existing links/bookmarks/SEO don't break, then the superseded entry is dropped.
Keep the Python impls on disk and served. Do not delete plots/*/implementations/python/highcharts.py in this PR — they keep serving for one release.
301-redirect old deep links:/{spec}/python/highcharts → /{spec}/javascript/highcharts, so bookmarks and SEO are preserved. (Recommended approach. Alternative: a one-release deprecation banner on the Python pages pointing at the JS variant. State which in the PR.)
LIB_TO_LANG['highcharts'] = 'javascript' in app/src/constants/index.ts. This deliberately points the library→language map at JS while the Python files still exist on disk; the redirect (step 3) bridges the gap. Document as time-boxed.
Generation targets JS only: ensure bulk-generate.yml / daily-regen.yml regenerate highcharts as the JavaScript variant; the Python files are frozen (served, not regenerated).
The acceptable fallback, if dual-serve + redirect is more than the team wants in one PR: flip the canonical entry to JS and immediately stop serving the Python pages, accepting that old /python/highcharts links 404. Recommended: the 301 redirect — cheap and preserves SEO. Decide and state in the PR.
Scope
1. Registry (core/constants.py)
Flip highcharts.language_id → "javascript", add framework: "none", refresh version/description/documentation_url for the JS library.
Rewrite prompts/library/highcharts.md from Python to JavaScript. Current file uses from highcharts_core.chart import Chart and an inline selenium screenshot blob — replace entirely with:
The JS Highcharts API: Highcharts.chart('container', { ... }).
Forbidden patterns: no highcharts-core (that's the Python wrapper we're leaving), no CDN <script src> (use the pinned npm bundle), no Highcharts modules that require a separate commercial add-on beyond the base license terms.
api/routers/specs.py: /api/specs/{spec}/highcharts/code?language=javascript returns the JS impl; the Python impl stays reachable for the deprecation window (e.g. ?language=python still 200s until the window closes, or is 301'd — match the frontend decision).
api/routers/debug.py, libraries.py: Highcharts now reports language_id: javascript; verify counters/columns follow.
Confirm /stats library count is unchanged (Highcharts is a move, not an add — still counts once).
6. Tests
tests/unit/core/test_constants.py: assert highchartslanguage_id == "javascript" and framework == "none".
Any test that pinned Highcharts as Python (fixtures, language-mapping assertions) gets updated.
A redirect test: /{spec}/python/highcharts → 301 → /{spec}/javascript/highcharts (or the chosen approach).
Frontend: LIB_TO_LANG / code-viewer test for highcharts → javascript.
7. Docs
docs/concepts/library-expansion.md: §1 table — Highcharts "In anyplot as" flips to JavaScript; §8 mark Phase 2 shipped; §9 record the deprecation-window execution (which approach: redirect vs. immediate cutover).
docs/reference/repository.md: note the temporary dual-location (python/highcharts.py frozen + javascript/highcharts.js canonical) during the window.
Acceptance criteria
core/constants.py: highcharts.language_id == "javascript", framework == "none", version/description refreshed for the JS library.
prompts/library/highcharts.md rewritten to the JavaScript Highcharts API + harness mount contract + commercial-license note.
gh workflow run impl-generate.yml -f specification_id=scatter-basic -f library=highcharts produces a passing JS Highcharts impl (plot-light.png + plot-dark.png + interactive HTML) in GCS.
Old /scatter-basic/python/highcharts 301-redirects to the JS variant (or the chosen §"deprecation window" approach is implemented and stated in the PR).
Python highcharts.py files remain on disk and (per the chosen approach) reachable for the deprecation window — not deleted in this PR.
/libraries shows Highcharts as a JavaScript library with the commercial-license badge; /stats library count unchanged (move, not add).
uv run pytest tests/unit tests/integration green; frontend yarn test --run, yarn tsc --noEmit, yarn lint clean.
Out of scope (separate follow-up, one release later)
Closing the deprecation window: delete plots/*/implementations/python/highcharts.py, drop the 301 redirect, remove highcharts-core (and any now-unused selenium-for-highcharts deps) from pyproject.toml. Track as a dedicated follow-up issue so the window actually closes — per §6 it's exactly one release cycle.
JS Highcharts modules requiring extra commercial add-ons beyond the base license — only the base library surface is in scope.
Part of the JavaScript rollout split: foundation in #8241, MUI X in its sibling issue. Reviewed against docs/concepts/library-expansion.md §§1/6/8/9 and the Julia rollout (#7613).
Summary
Migrate Highcharts from its current Python entry (
highcharts-corewrapper) to a native JavaScript entry, executed as a deprecation window so existing links don't break. This is Phase 2 ofdocs/concepts/library-expansion.mdand the second of three issues splitting the JavaScript rollout:This is a meta / infrastructure issue, not a spec request — do not apply the
spec-requestlabel.Why move it
Per
docs/concepts/library-expansion.md§6 (the "most-used variant" rule) and §1:The native
highcharts.jsoutweighs the Pythonhighcharts-corewrapper by ~200× weekly downloads — far past the ≥ 3× threshold — so the rule mandates the canonical entry move to JavaScript. Highcharts is the industry standard in finance/news dashboards; the JS audience is who actually uses it.License note (unchanged): Commercial, free for non-commercial use. Keep the license tag and surface it prominently on the plot pages — same as today.
The careful bit: deprecation window (§6 + §9)
§6's "Exception — deprecation window": when a library moves languages, both entries may co-exist for one release cycle so existing links/bookmarks/SEO don't break, then the superseded entry is dropped.
Execution:
core/constants.py):highchartsentry'slanguage_id"python"→"javascript",framework: "none", refreshversion+descriptionto the JS library (verify version against feat(javascript): add JavaScript runtime + render harness + Chart.js, D3.js, ECharts (Phase 1) #8241'spackage-lock.json). New impls generate underimplementations/javascript/highcharts.js.plots/*/implementations/python/highcharts.pyin this PR — they keep serving for one release./{spec}/python/highcharts→/{spec}/javascript/highcharts, so bookmarks and SEO are preserved. (Recommended approach. Alternative: a one-release deprecation banner on the Python pages pointing at the JS variant. State which in the PR.)LIB_TO_LANG['highcharts'] = 'javascript'inapp/src/constants/index.ts. This deliberately points the library→language map at JS while the Python files still exist on disk; the redirect (step 3) bridges the gap. Document as time-boxed.bulk-generate.yml/daily-regen.ymlregeneratehighchartsas the JavaScript variant; the Python files are frozen (served, not regenerated).Scope
1. Registry (
core/constants.py)highcharts.language_id→"javascript", addframework: "none", refreshversion/description/documentation_urlfor the JS library.highchartsis already inINTERACTIVE_LIBRARIES— leave it (the JS render path is HTML-based, same as the other JS libs from feat(javascript): add JavaScript runtime + render harness + Chart.js, D3.js, ECharts (Phase 1) #8241).2. Workflows
case "$LIBRARY"table (from feat(javascript): add JavaScript runtime + render harness + Chart.js, D3.js, ECharts (Phase 1) #8241) already mapschartjs|d3|echarts|highcharts → (javascript, .js). If feat(javascript): add JavaScript runtime + render harness + Chart.js, D3.js, ECharts (Phase 1) #8241 didn't includehighchartsin that arm yet, add it here. No other workflow change —setup-node, the harness, and version detection are inherited from feat(javascript): add JavaScript runtime + render harness + Chart.js, D3.js, ECharts (Phase 1) #8241.3. Prompt
prompts/library/highcharts.mdfrom Python to JavaScript. Current file usesfrom highcharts_core.chart import Chartand an inline selenium screenshot blob — replace entirely with:Highcharts.chart('container', { ... }).#container; harness handles HTML scaffold + Playwright screenshot — no inline HTML/screenshot code in the snippet).ANYPLOT_THEMElight/dark chrome mapping (Highchartstheme/chart.backgroundColor/ axis & label colors).deviceScaleFactor.//-comment header block (// Library: Highcharts <ver> | Node 22).highcharts-core(that's the Python wrapper we're leaving), no CDN<script src>(use the pinned npm bundle), no Highcharts modules that require a separate commercial add-on beyond the base license terms.4. Frontend (
app/src/)constants/index.ts:LIB_TO_LANG['highcharts'] = 'javascript'.LIB_ABBREV/LIBRARIESalready containhighcharts— no add, just the language flip.LIB_TO_FRAMEWORK['highcharts'] = 'none'(map introduced in feat(javascript): add JavaScript runtime + render harness + Chart.js, D3.js, ECharts (Phase 1) #8241)./{spec}/python/highcharts→/{spec}/javascript/highcharts(router-level 301, or the chosen §"deprecation window" approach).LibraryCard.tsx: refresh the Highcharts description to the JS library; keep the commercial-license badge.javascript(grammar already registered in feat(javascript): add JavaScript runtime + render harness + Chart.js, D3.js, ECharts (Phase 1) #8241) — verify the old Python highlighting path isn't pinned anywhere forhighcharts.5. Backend (
api/)api/routers/specs.py:/api/specs/{spec}/highcharts/code?language=javascriptreturns the JS impl; the Python impl stays reachable for the deprecation window (e.g.?language=pythonstill 200s until the window closes, or is 301'd — match the frontend decision).api/routers/debug.py,libraries.py: Highcharts now reportslanguage_id: javascript; verify counters/columns follow./statslibrary count is unchanged (Highcharts is a move, not an add — still counts once).6. Tests
tests/unit/core/test_constants.py: asserthighchartslanguage_id == "javascript"andframework == "none"./{spec}/python/highcharts→ 301 →/{spec}/javascript/highcharts(or the chosen approach).LIB_TO_LANG/ code-viewer test forhighcharts → javascript.7. Docs
docs/concepts/library-expansion.md: §1 table — Highcharts "In anyplot as" flips to JavaScript; §8 mark Phase 2 shipped; §9 record the deprecation-window execution (which approach: redirect vs. immediate cutover).docs/reference/repository.md: note the temporary dual-location (python/highcharts.pyfrozen +javascript/highcharts.jscanonical) during the window.Acceptance criteria
core/constants.py:highcharts.language_id == "javascript",framework == "none", version/description refreshed for the JS library.prompts/library/highcharts.mdrewritten to the JavaScript Highcharts API + harness mount contract + commercial-license note.gh workflow run impl-generate.yml -f specification_id=scatter-basic -f library=highchartsproduces a passing JS Highcharts impl (plot-light.png+plot-dark.png+ interactive HTML) in GCS./scatter-basic/javascript/highchartsloads code + preview in light & dark;?language=javascript200s./scatter-basic/python/highcharts301-redirects to the JS variant (or the chosen §"deprecation window" approach is implemented and stated in the PR).highcharts.pyfiles remain on disk and (per the chosen approach) reachable for the deprecation window — not deleted in this PR./librariesshows Highcharts as a JavaScript library with the commercial-license badge;/statslibrary count unchanged (move, not add).uv run pytest tests/unit tests/integrationgreen; frontendyarn test --run,yarn tsc --noEmit,yarn lintclean.docs/concepts/library-expansion.md§1/§8/§9 updated; Phase 2 marked shipped.Out of scope (separate follow-up, one release later)
plots/*/implementations/python/highcharts.py, drop the 301 redirect, removehighcharts-core(and any now-unused selenium-for-highcharts deps) frompyproject.toml. Track as a dedicated follow-up issue so the window actually closes — per §6 it's exactly one release cycle.Part of the JavaScript rollout split: foundation in #8241, MUI X in its sibling issue. Reviewed against
docs/concepts/library-expansion.md§§1/6/8/9 and the Julia rollout (#7613).