Closed Issues¶
Resolved and rejected issues from the panel-live project.
~~P0 — Design Extensible User/Developer-Facing API~~¶
Resolved. The API uses a single <panel-live> custom element (Light DOM) with mode="app|editor|playground". Full specification covers HTML attributes, child elements, JS API, CSS custom properties, and events.
~~P0 — Settle on Name~~¶
Resolved. The name is panel-live, mirroring the "shinylive" convention.
~~P0 — Determine Repository~~¶
Resolved. Separate panel-live repo under panel-extensions GitHub organization.
~~P0 — Does Not Work with panel-material-ui~~¶
Resolved. Confirmed working — pmui.Button(label="Click Me") renders successfully. The original issue was related to an older version.
~~P1 — Evaluate PyScript as Foundation~~¶
Rejected. PyScript adds dependency risk, has stability concerns, and provides no meaningful value for Panel's use case. The POC confirms everything works without it.
~~P1 — Folder and File Structure~~¶
Resolved. Repo structure finalized: src/panel_live/ (Python), lib/ (JS/CSS), docs/, tests/, examples/.
~~P1 — Separate CSS~~¶
Resolved. CSS extracted from JS into standalone panel-live.css (372 lines). CSS custom properties (--pl-*) with light/dark presets preserved.
~~P1 — Cannot Select Code with Mouse~~¶
Resolved. CodeMirror 5 integration works correctly. The original issue was caused by overlapping elements in the old architecture.
~~P1 — Interactive API Explorer Page~~¶
Resolved. Full interactive explorer at docs/api-explorer.html with mode/theme/layout controls, 14 example snippets, CSS variable controls, and live HTML generation.
~~P1 — Loading Progress (All Modes)~~¶
Resolved. All 3 modes use identical loading UI with status bar, spinner, and stage progression text.
~~P2 — Multi-file Support~~¶
Resolved. <panel-file> custom element supports multi-file apps with name, entrypoint, and src attributes. Files written to Pyodide's virtual filesystem.
~~P2 — Requirements / Package Specification~~¶
Resolved. <panel-requirements> element allows explicit pip package specification. Auto-detection via find_requirements() as fallback.
~~P2 — MkDocs Extension~~¶
Resolved. src/panel_live/fences.py implements custom fence for pymdownx.superfences. Supports all attributes via ```{.panel ...} syntax.
~~P2 — Align Styles Across Modes~~¶
Resolved. Unified --pl-* CSS variable system shared by all 3 modes. Styles in separate panel-live.css.
~~P2 — Customizable Styling / Branding~~¶
Resolved. Full --pl-* CSS variable system with light/dark presets. theme="auto" detects prefers-color-scheme.
~~P2 — Playground Layout Options~~¶
Resolved. layout attribute with "horizontal" and "vertical" values.
~~P2 — Pixi Commands~~¶
Resolved. pixi.toml defines tasks across multiple environments: test, lint, docs, build, serve.
~~P2 — GitHub Actions CI/CD~~¶
Resolved. CI with pytest, Playwright UI tests, and pre-commit linting on PRs and pushes.
~~P3 — Dark Theme Support~~¶
Resolved. theme="auto"|"light"|"dark" with prefers-color-scheme detection, Dracula for dark, CodeMirror default for light.
~~P1 — Duplicate Execution Logic~~¶
Resolved. Single runPanelCode() function with 3-branch execution strategy. No iframe mode, no duplication.
~~P1 — Copy Code Button~~¶
Resolved. Copy button with navigator.clipboard.writeText() and "Copied!" toast feedback in all editor/playground modes. "Copy error" button on error panels.
~~P2 — Docs Theme Toggle Does Not Update Instances~~¶
Resolved. MutationObserver watches data-md-color-scheme on document.body and updates CodeMirror theme dynamically. MediaQuery listener handles system preference changes.
~~P2 — Landing Page Should Showcase Generic Python Support~~¶
Resolved. Landing page includes a matplotlib example (no Panel imports) immediately after the default slider demo, under a "Works with any Python" section.
~~P2 — Revise README for Broader Audience~~¶
Resolved. README leads with "Write, edit, and run Python interactively in the browser" and "Turn any web page into an interactive Python playground". No Panel-centric framing.
~~P1 — Fix events/ Page Navigation~~¶
Resolved. Events page moved from under "Styling" to its own "Events" section in zensical.toml navigation. The page now appears correctly in the sidebar.
~~P2 — Rename "Competitors" to "Alternatives"~~¶
Resolved. All references to "competitors" in docs/explanation/design.md replaced with "alternatives" — section heading, comparison table intro, and differentiators list.
~~P2 — Enable "org" Mode in MkDocs~~¶
Resolved. mode="org" in the fence syntax delegates to pymdownx.superfences.fence_code_format() to render a standard syntax-highlighted code block. No <panel-live> element is inserted. Documented in how-to/mode.md and reference/html-api.md. Tests in tests/test_fences.py.
~~P1 — Handle Python Errors Properly~~¶
Resolved. Tracebacks are parsed into structured frames. User-code frames (<exec>, <module>, <string>, <ast>) are shown prominently; internal Pyodide/Panel frames are hidden behind a collapsible <details> section. Error type and message are displayed in a header. A "Copy error" button copies the full traceback. Remaining: syntax highlighting in traceback, async/callback error capture.
~~P1 — Warn on Invalid Source URLs~~¶
Resolved. fetchPythonSource() validates HTTP status, checks Content-Type header, and detects HTML responses. Invalid URLs produce a clear error message instead of a cryptic SyntaxError.
~~P1 — Build System~~¶
Resolved. esbuild bundles ES modules from lib/ into dist/panel-live.js (main IIFE) + dist/panel-live-worker.js (worker IIFE) + dist/panel-live.css with source maps. Build script: build.mjs.
~~P1 — Python Code as String Concatenation~~¶
Resolved. 6 Python bootstrap scripts in lib/python/ (servable-setup, servable-render, servable-target-setup, servable-target-render, expression-exec, expression-render). Imported as text strings via esbuild .py text loader.
~~P1 — Display Print Statements~~¶
Resolved. sys.stdout and sys.stderr are captured via io.StringIO() in all 3 execution branches (servable, servable-target, expression). Output is rendered as a <pre class="pl-stdout"> element above the app output.
~~P2 — Tracking Prevention Blocks CDN Resources~~¶
Resolved. CodeMirror 6 is bundled via esbuild. No CDN dependency for the editor.
~~P2 — CodeMirror 5 is Legacy~~¶
Resolved. Full CodeMirror 6 migration with ESM imports, bundled via esbuild. Python syntax highlighting, oneDark theme, VS Code keybindings.
~~P2 — Auto Layout Based on Window Size~~¶
Resolved. layout="auto" switches between horizontal (wide) and vertical (narrow ≤768px) via CSS @media query on data-layout="auto" attribute. Auto is now the default for playground mode.
~~P2 — Error Boundaries Between Apps~~¶
Resolved. Bokeh curdoc is reset to a fresh Document() in a finally block after each execution, preventing cross-contamination between apps.
~~P2 — VS Code Keyboard Shortcuts~~¶
Resolved. VS Code keybindings added via CM6: Ctrl+D (select next occurrence), Ctrl+Shift+K (delete line), Ctrl+L (select line), Ctrl+/ (toggle comment).
~~P2 — Support GitHub URLs in src Attribute~~¶
Resolved. resolveSourceUrl() detects GitHub blob URLs and converts them to raw.githubusercontent.com URLs before fetching.
~~P3 — Link to panel-live Docs from Editor / Playground~~¶
Resolved. A ? help link button is added to all editor and playground headers, linking to the panel-live docs site.
~~P0 — Web Worker Support~~¶
Resolved. Pyodide now runs in a Dedicated Worker (singleton per page). The main thread stays responsive during load and execution — spinners animate smoothly, the page remains interactive. Architecture: panel-live-worker.js runs Pyodide/micropip/user code in the worker; worker-bridge.js manages the worker from the main thread, handling Bokeh embed_items(), bidirectional document sync via JSON patches, real-time print() streaming, and error rendering. All 3 execution branches (servable, servable-target, expression) are unified into worker-setup.py + worker-render.py. The worker has an internal execution queue for serializing multi-element execution.
~~P1 — Python Code as String Concatenation (Update)~~¶
Updated. The 6 branch-specific Python scripts (servable-setup, servable-render, servable-target-setup, servable-target-render, expression-exec, expression-render) have been unified into 2 scripts: worker-setup.py (all branches) and worker-render.py (serialization via _doc_json()). Still imported as text strings via esbuild .py text loader.
~~P1 — Display Print Statements (Update)~~¶
Updated. Print output now streams in real-time via the Web Worker's StreamingWriter class, which calls JS callbacks on each write(). Output appears incrementally in a <pre class="pl-stdout"> element as code executes, rather than only after completion.
~~P1 — JS Modular Architecture~~¶
Resolved. Monolithic panel-live.js decomposed into 13 focused ES modules in lib/. Each module has a single responsibility with named exports: config.js (configuration/CDN URLs), utils.js (utilities), theme.js (dark mode), codemirror.js (editor), worker-bridge.js (worker communication), error-renderer.js (error display), helper-elements.js (child elements), url-sharing.js (URL encoding), panel-live-element.js (custom element), controller.js (runtime API), api.js (public API), panel-live-worker.js (Dedicated Worker), and index.js (entry point). Bundled by esbuild into dist/panel-live.js (main IIFE) + dist/panel-live-worker.js (worker IIFE) + dist/panel-live.css.
~~P1 — Vitest Unit Test Suite~~¶
Resolved. 69 Vitest unit tests across 6 test modules covering config, utils, theme, url-sharing, error-renderer, and worker-bridge. Tests run in a jsdom environment via pixi run test-js. V8 coverage reporting available via pixi run test-js-coverage.
~~P1 — Run Button Causes Layout Flicker~~¶
Resolved. Output height preserved via minHeight lock during re-run. Status bar uses absolute positioning over the output area. No visible layout shift.
~~P2 — Improve UX (Buttons, Tooltips, Layout)~~¶
Resolved. Tooltips added to all buttons. Code toggle redesigned with "Expand Code" / "Collapse Code" labels. Toggle buttons use .pl-btn secondary class for visual consistency with Copy/Share/Reset buttons.
~~P2 — Show Web Component Syntax in Docs~~¶
Resolved. All how-to guide pages systematically show both MkDocs fence syntax and <panel-live> HTML web component syntax.
~~P2 — Working Examples Across How-To Guides~~¶
Resolved. All how-to guides include live <panel-live> elements that render and execute. No indicative-only examples remain.
~~P2 — Update Mini-Coi Documentation~~¶
Resolved. mini-coi.js setup documented in docs/how-to/mkdocs-integration.md with usage instructions and troubleshooting.
~~P2 — Document MkDocs Integration for Third-Party Users~~¶
Resolved. docs/how-to/mkdocs-integration.md provides complete setup instructions including zensical.toml/mkdocs.yml configuration, custom fence registration, asset setup, and troubleshooting.
~~P1 — Automated Testing~~¶
Resolved. Expanded from 69 to 123 Vitest JS unit tests across 9 test modules. New test files: helper-elements.test.js (16 tests for <panel-file>, <panel-requirements>, <panel-example>), api.test.js (12 tests for PanelLive.configure() and PanelLive.mount()), controller.test.js (6 tests for PanelLiveController), plus 18 message validation tests in worker-bridge.test.js.
~~P1 — Systematically Test Documentation~~¶
Resolved. All documentation pages reviewed. Code examples verified as working or clearly marked as illustrative. Prose descriptions added to examples page for LLM accessibility. All how-to guides include live <panel-live> elements.
~~P2 — Simplify Index Page Examples for Mobile~~¶
Resolved. Editor example on index.md simplified from 35-line color palette generator to an 11-line greeting demo using TextInput + IntSlider. Fits comfortably on mobile screens.
~~P2 — Playground Default Example~~¶
Resolved. Playground default replaced with a welcoming example featuring name input, emoji greeting, and link to panel-live docs. Two legacy examples modernized from param.watch() to pn.bind() pattern.
~~P2 — postMessage Security~~¶
Resolved. Structural message validation added to both sides: _validateWorkerMessage() in worker-bridge.js whitelists valid message types and checks type-specific required fields; _validateMainMessage() in panel-live-worker.js does the same for incoming messages. Invalid messages rejected with console.warn. Design rationale documented in docs/explanation/design.md.
~~P2 — CSP Nonce Support~~¶
Resolved. styleNonce added to _defaults in config.js. loadScript() and loadCSS() in utils.js apply the nonce to dynamically created <script> and <link> elements when truthy. Design rationale documented in docs/explanation/design.md.
~~P2 — Document Known Limitations~~¶
Resolved. docs/reference/known-limitations.md covers all limitations: no threads, no subprocess, 2GB memory limit, time.sleep busy-wait, C extension packages, no .plot()/.show(), source code exposure, CORS constraints, performance expectations, and Pyodide version coupling. Landing page links to it.
~~P2 — Document Browser Sandbox Security Model~~¶
Resolved. docs/explanation/security.md explains the client-side execution model, what the browser sandbox prevents, source code visibility, COOP/COEP context, and comparison with server-side execution.
~~P2 — Browser Compatibility Matrix~~¶
Resolved. docs/reference/browser-compatibility.md includes browser support table (Chrome 90+, Firefox 90+, Edge 90+, Safari 16.4+, mobile variants), WebAssembly/SharedArrayBuffer requirements, performance expectations, known platform-specific issues, and minimum hardware recommendations.
~~P2 — Self-Hosting Documentation~~¶
Resolved. docs/how-to/self-hosting.md covers what to download, directory structure, PanelLive.configure() setup, server COOP/COEP headers (Apache, Nginx, Caddy), and verification checklist.
~~P2 — Service Worker Fragility Behind Auth Proxies~~¶
Resolved. docs/how-to/auth-proxy-setup.md documents the problem, symptoms, server-side COOP/COEP header configuration for Apache/Nginx/Caddy/Cloudflare/Netlify/Vercel, and when mini-coi.js suffices vs when server headers are required.
~~P2 — Document Claude.ai Usage~~¶
Resolved. docs/how-to/claude-artifacts.md documents how panel-live works in Claude.ai HTML artifacts, including example artifact HTML, sandbox constraints, and tips for prompting Claude.
~~P2 — LLM Page Accessibility~~¶
Resolved. Prose descriptions added before every example in docs/examples.md, explaining what APIs and patterns each example demonstrates. All documentation pages have clear semantic headings and structured content.
~~P2 — Review label Attribute Naming~~¶
Resolved. Decision: keep label. Rationale documented in docs/how-to/label.md — it's the most semantic term, aligns with HTML/accessibility conventions, and leaves title/description available for future attributes.
~~P2 — Panel Live Skill for Claude Code~~¶
Resolved. skills/panel-live.md created with quick start (HTML + MkDocs fence), three modes with examples, all HTML attributes, child elements, JS API, constraints, and architecture summary.
~~P2 — Iframe Embedding~~¶
Resolved. docs/how-to/iframe-embedding.md documents basic iframe patterns, COOP/COEP requirements, recommended iframe attributes, same-origin vs cross-origin considerations, and known limitations.
~~P2 — DeckGL Extension Not Working in WASM Runtime~~¶
Resolved. DeckGL works using a JSON spec approach with pn.pane.DeckGL(json_spec, ...) — this bypasses the @deck.gl/core loading issue that affected pn.extension("deckgl"). Example moved from "Not Working" to the main examples page.
~~P2 — Requirements Whitespace Splitting~~¶
Resolved. worker-bridge.js install() now splits by any whitespace (not just newlines). Fixes <panel-requirements>fastparquet requests</panel-requirements> producing a single invalid package name.
~~P2 — Package Aliases (packageAliases)~~¶
Resolved. packageAliases config maps package names to wheel URLs. Resolved in both worker-bridge.js (explicit install) and panel-live-worker.js (auto-detected requirements). Passed from main thread to worker during init. Empty defaults — infrastructure for future use (e.g. DuckDB once a compatible wheel exists).
~~P2 — Playground URL on Subpages~~¶
Resolved. _updatePlaygroundLink() derives site root from <script src="...panel-live.js"> tag. Previously resolved relative to current page, producing wrong URLs from subpages like /examples/.
~~P2 — CSS Button Height and Toggle Visibility~~¶
Resolved. .pl-btn uses display: inline-flex; align-items: center instead of line-height: 1. Playground link stays visible when code is expanded (only Copy is hidden via .copy-btn.pl-toggle-btn selector).